From 05752890411cee29464f4edc5e2f1bb904679f5b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 26 May 2012 11:43:24 -0300 Subject: [PATCH] [media] dvb_usb_v2: remote controller changes Add .get_rc_config() callback and remove old static configs. Refactor remote controller routines. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dvb_usb.h | 20 ++-- drivers/media/dvb/dvb-usb/dvb_usb_remote.c | 117 ++++++++++----------- 2 files changed, 67 insertions(+), 70 deletions(-) diff --git a/drivers/media/dvb/dvb-usb/dvb_usb.h b/drivers/media/dvb/dvb-usb/dvb_usb.h index 716f17455669..0715e72259f6 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb.h +++ b/drivers/media/dvb/dvb-usb/dvb_usb.h @@ -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 diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_remote.c b/drivers/media/dvb/dvb-usb/dvb_usb_remote.c index b8d2cb193bb1..22d7790e7c42 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb_remote.c +++ b/drivers/media/dvb/dvb-usb/dvb_usb_remote.c @@ -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; } -- 2.20.1