[media] dvb_usb_v2: remote controller changes
authorAntti Palosaari <crope@iki.fi>
Sat, 26 May 2012 14:43:24 +0000 (11:43 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 4 Aug 2012 10:56:22 +0000 (07:56 -0300)
Add .get_rc_config() callback and remove old static configs.
Refactor remote controller routines.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/dvb-usb/dvb_usb.h
drivers/media/dvb/dvb-usb/dvb_usb_remote.c

index 716f174..0715e72 100644 (file)
@@ -157,16 +157,14 @@ struct dvb_usb_adapter_properties {
  * @rc_interval: time in ms between two queries.
  * @bulk_mode: device supports bulk mode for RC (disable polling mode)
  */
-struct dvb_rc {
-       char *rc_codes;
-       u64 protocol;
+struct dvb_usb_rc {
+       char *map_name;
        u64 allowed_protos;
-       enum rc_driver_type driver_type;
        int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
-       char *module_name;
-       int (*rc_query) (struct dvb_usb_device *d);
-       int rc_interval;
-       bool bulk_mode;                         /* uses bulk mode */
+       int (*query) (struct dvb_usb_device *d);
+       int interval;
+       const enum rc_driver_type driver_type;
+       bool bulk_mode;
 };
 
 /**
@@ -207,6 +205,7 @@ struct dvb_rc {
  */
 #define MAX_NO_OF_ADAPTER_PER_DEVICE 2
 struct dvb_usb_device_properties {
+       const char *driver_name;
        struct module *owner;
        short *adapter_nr;
 
@@ -234,18 +233,18 @@ struct dvb_usb_device_properties {
        int (*power_ctrl)       (struct dvb_usb_device *, int);
        int (*read_config) (struct dvb_usb_device *d);
        int (*read_mac_address) (struct dvb_usb_device *, u8 []);
+       int (*tuner_attach) (struct dvb_frontend *);
 
 #define WARM                  0
 #define COLD                  1
        int (*identify_state) (struct dvb_usb_device *);
        int (*init) (struct dvb_usb_device *);
+       int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *);
 
        struct i2c_algorithm *i2c_algo;
 
        int generic_bulk_ctrl_endpoint;
        int generic_bulk_ctrl_endpoint_response;
-
-       struct dvb_rc rc;
 };
 
 /**
@@ -373,6 +372,7 @@ struct dvb_usb_device {
        struct dvb_usb_device_properties props;
        const char *name;
        const char *rc_map;
+       struct dvb_usb_rc rc;
        struct usb_device *udev;
 
 #define DVB_USB_STATE_INIT        0x000
index b8d2cb1..22d7790 100644 (file)
@@ -16,9 +16,9 @@
  */
 static void dvb_usb_read_remote_control(struct work_struct *work)
 {
-       struct dvb_usb_device *d =
-               container_of(work, struct dvb_usb_device, rc_query_work.work);
-       int err;
+       struct dvb_usb_device *d = container_of(work,
+                       struct dvb_usb_device, rc_query_work.work);
+       int ret;
 
        /* TODO: need a lock here.  We can simply skip checking for the remote
           control if we're busy. */
@@ -26,87 +26,82 @@ static void dvb_usb_read_remote_control(struct work_struct *work)
        /* when the parameter has been set to 1 via sysfs while the
         * driver was running, or when bulk mode is enabled after IR init
         */
-       if (dvb_usb_disable_rc_polling || d->props.rc.bulk_mode)
+       if (dvb_usb_disable_rc_polling || d->rc.bulk_mode)
                return;
 
-       err = d->props.rc.rc_query(d);
-       if (err)
-               err("error %d while querying for an remote control event.",
-                       err);
+       ret = d->rc.query(d);
+       if (ret < 0)
+               err("error %d while querying for an remote control event", ret);
 
        schedule_delayed_work(&d->rc_query_work,
-                             msecs_to_jiffies(d->props.rc.rc_interval));
+                             msecs_to_jiffies(d->rc.interval));
 }
 
-static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
+int dvb_usb_remote_init(struct dvb_usb_device *d)
 {
-       int err, rc_interval;
+       int ret;
        struct rc_dev *dev;
 
+       if (dvb_usb_disable_rc_polling || !d->props.get_rc_config)
+               return 0;
+
+       ret = d->props.get_rc_config(d, &d->rc);
+       if (ret < 0)
+               goto err;
+
        dev = rc_allocate_device();
-       if (!dev)
-               return -ENOMEM;
-
-       dev->driver_name = d->props.rc.module_name;
-       dev->map_name = d->rc_map;
-       dev->change_protocol = d->props.rc.change_protocol;
-       dev->allowed_protos = d->props.rc.allowed_protos;
-       dev->driver_type = d->props.rc.driver_type;
-       usb_to_input_id(d->udev, &dev->input_id);
+       if (!dev) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       dev->dev.parent = &d->udev->dev;
        dev->input_name = "IR-receiver inside an USB DVB receiver";
+       usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+       strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
        dev->input_phys = d->rc_phys;
-       dev->dev.parent = &d->udev->dev;
+       usb_to_input_id(d->udev, &dev->input_id);
+       /* TODO: likely RC-core should took const char * */
+       dev->driver_name = (char *) d->props.driver_name;
+       dev->driver_type = d->rc.driver_type;
+       dev->allowed_protos = d->rc.allowed_protos;
+       dev->change_protocol = d->rc.change_protocol;
        dev->priv = d;
-
-       /* leave remote controller enabled even there is no default map */
-       if (dev->map_name == NULL)
-               dev->map_name = RC_MAP_EMPTY;
-
-       err = rc_register_device(dev);
-       if (err < 0) {
+       /* select used keymap */
+       if (d->rc.map_name)
+               dev->map_name = d->rc.map_name;
+       else if (d->rc_map)
+               dev->map_name = d->rc_map;
+       else
+               dev->map_name = RC_MAP_EMPTY; /* keep rc enabled */
+
+       ret = rc_register_device(dev);
+       if (ret < 0) {
                rc_free_device(dev);
-               return err;
+               goto err;
        }
 
        d->input_dev = NULL;
        d->rc_dev = dev;
 
-       if (!d->props.rc.rc_query || d->props.rc.bulk_mode)
-               return 0;
-
-       /* Polling mode - initialize a work queue for handling it */
-       INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
+       /* start polling if needed */
+       if (d->rc.query && !d->rc.bulk_mode) {
+               /* initialize a work queue for handling polling */
+               INIT_DELAYED_WORK(&d->rc_query_work,
+                               dvb_usb_read_remote_control);
 
-       rc_interval = d->props.rc.rc_interval;
-
-       info("schedule remote query interval to %d msecs.", rc_interval);
-       schedule_delayed_work(&d->rc_query_work,
-                             msecs_to_jiffies(rc_interval));
-
-       return 0;
-}
-
-int dvb_usb_remote_init(struct dvb_usb_device *d)
-{
-       int err;
-
-       if (dvb_usb_disable_rc_polling)
-               return 0;
-
-       if (d->props.rc.module_name == NULL)
-               return 0;
-
-       usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
-       strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
-
-       /* Start the remote-control polling. */
-       err = rc_core_dvb_usb_remote_init(d);
-       if (err)
-               return err;
+               info("schedule remote query interval to %d msecs",
+                               d->rc.interval);
+               schedule_delayed_work(&d->rc_query_work,
+                               msecs_to_jiffies(d->rc.interval));
+       }
 
        d->state |= DVB_USB_STATE_REMOTE;
 
        return 0;
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
 }
 
 int dvb_usb_remote_exit(struct dvb_usb_device *d)
@@ -115,6 +110,8 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
                cancel_delayed_work_sync(&d->rc_query_work);
                rc_unregister_device(d->rc_dev);
        }
+
        d->state &= ~DVB_USB_STATE_REMOTE;
+
        return 0;
 }