a800 dvb rc changes
Subsystems (5)
Sean Young
maintainercover a800 dvb rc changes
Various changes to make the a800 dvb adapter work again and to improve its ir receiver.
Sean Young (7):
media: dvb: i2c transfers over usb cannot be done from stack
media: dvb: a800: port to rc-core
media: rc: avermedia keymap for a800
media: rc: ensure that protocols are enabled for scancode drivers
media: rc: dvb: use dvb device name for rc device
media: rc: if protocols can't be changed, don't be writable
media: rc: include device name in rc udev event
drivers/media/cec/cec-core.c | 1 - drivers/media/dvb-frontends/dib3000mc.c | 50 ++++++++++++++++----- drivers/media/dvb-frontends/dvb-pll.c | 21 ++++++--- drivers/media/i2c/ir-kbd-i2c.c | 1 - drivers/media/rc/keymaps/rc-avermedia-m135a.c | 3 +- drivers/media/rc/rc-main.c | 33 +++++++++++--- drivers/media/tuners/mt2060.c | 59 +++++++++++++++++++----- drivers/media/usb/dvb-usb/a800.c | 65 ++++++--------------------- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 2 +- 9 files changed, 145 insertions(+), 90 deletions(-)
Signature · 1 line
2.13.5
Sean Young
maintainerPATCH 1/7 media: dvb: i2c transfers over usb cannot be done from stack
Since commit 29d2fef8be11 ("usb: catch attempts to submit urbs with a vmalloc'd transfer buffer"), the AverMedia AverTV DVB-T USB 2.0 (a800) fails to probe.
--- drivers/media/dvb-frontends/dib3000mc.c | 50 ++++++++++++++++++++++------ drivers/media/dvb-frontends/dvb-pll.c | 21 +++++++++--- drivers/media/tuners/mt2060.c | 59 ++++++++++++++++++++++++++------- 3 files changed, 102 insertions(+), 28 deletions(-)
drivers/media/dvb-frontends/dib3000mc.c +39 -11
@@ -55,29 +55,57 @@ struct dib3000mc_state {static u16 dib3000mc_read_word (struct dib3000mc_state *state,u16 reg) { -u8 wb[2 ] = { (reg >>8 ) |0x80 , reg &0xff }; -u8 rb[2 ];struct i2c_msg msg[2 ] = { - { .addr = state->i2c_addr >>1 , .flags =0 , .buf = wb, .len =2 }, - { .addr = state->i2c_addr >>1 , .flags =I2C_M_RD , .buf = rb, .len =2 }, + { .addr = state->i2c_addr >>1 , .flags =0 , .len =2 }, + { .addr = state->i2c_addr >>1 , .flags =I2C_M_RD , .len =2 }, }; +u16 word; +u8 *b; + + b =kmalloc (4 ,GFP_KERNEL ); +if (!b) +return 0 ; + + b[0 ] = (reg >>8 ) |0x80 ; + b[1 ] = reg; + b[2 ] =0 ; + b[3 ] =0 ; + + msg[0 ].buf = b; + msg[1 ].buf = b +2 ;if (i2c_transfer (state->i2c_adap, msg,2 ) !=2 )dprintk ("i2c read error on %d\n" ,reg); -return (rb[0 ] <<8 ) | rb[1 ]; + word = b[2 ] <<8 | b[3 ]; +kfree (b); + +return word; }static int dib3000mc_write_word (struct dib3000mc_state *state,u16 reg,u16 val) { -u8 b[4 ] = { - (reg >>8 ) &0xff , reg &0xff , - (val >>8 ) &0xff , val &0xff , - };struct i2c_msg msg = { - .addr = state->i2c_addr >>1 , .flags =0 , .buf = b, .len =4 + .addr = state->i2c_addr >>1 , .flags =0 , .len =4 }; -return i2c_transfer (state->i2c_adap, &msg,1 ) !=1 ? -EREMOTEIO :0 ; +int rc; +u8 *b; + + b =kmalloc (4 ,GFP_KERNEL ); +if (!b) +return -ENOMEM ; + + b[0 ] = reg >>8 ; + b[1 ] = reg; + b[2 ] = val >>8 ; + b[3 ] = val; + + msg.buf = b; + + rc =i2c_transfer (state->i2c_adap, &msg,1 ) !=1 ? -EREMOTEIO :0 ; +kfree (b); + +return rc; }static int dib3000mc_identify (struct dib3000mc_state *state)
drivers/media/dvb-frontends/dvb-pll.c +16 -5
@@ -753,13 +753,18 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,struct i2c_adapter *i2c, unsigned int pll_desc_id) { - u8 b1 [] = { 0 }; -struct i2c_msg msg = { .addr = pll_addr, .flags =I2C_M_RD , - .buf = b1, .len =1 }; + u8 *b1; +struct i2c_msg msg = { .addr = pll_addr, .flags =I2C_M_RD , .len =1 };struct dvb_pll_priv *priv =NULL ;int ret;const struct dvb_pll_desc *desc; + b1 =kmalloc (1 ,GFP_KERNEL ); +if (!b1) +return NULL ; + + msg.buf = b1; +if ((id[dvb_pll_devcount] >DVB_PLL_UNDEFINED ) && (id[dvb_pll_devcount] <ARRAY_SIZE (pll_list))) pll_desc_id = id[dvb_pll_devcount];
@@ -773,15 +778,19 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, fe->ops.i2c_gate_ctrl (fe,1 ); ret =i2c_transfer (i2c, &msg,1 ); -if (ret !=1 ) +if (ret !=1 ) { +kfree (b1);return NULL ; + }if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl (fe,0 ); } priv =kzalloc (sizeof (struct dvb_pll_priv ),GFP_KERNEL ); -if (priv ==NULL ) +if (!priv) { +kfree (b1);return NULL ; + } priv->pll_i2c_address = pll_addr; priv->i2c = i2c;
@@ -811,6 +820,8 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, "insmod option" : "autodetected"); } +kfree (b1); +return fe; }EXPORT_SYMBOL (dvb_pll_attach);
drivers/media/tuners/mt2060.c +47 -12
99 lines not on this page · raw message
Signature · 1 line
2.13.5
Sean Young
maintainerPATCH 2/7 media: dvb: a800: port to rc-core
In reply to Sean YoungThis receiver only accepts nec16 messages, I've tried many other protocols and they're all dropped.
--- drivers/media/usb/dvb-usb/a800.c | 65 +++++++++------------------------------- 1 file changed, 14 insertions(+), 51 deletions(-)
drivers/media/usb/dvb-usb/a800.c +14 -51
@@ -37,48 +37,9 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_prreturn 0 ; } -static struct rc_map_table rc_map_a800_table[] = { - {0x0201 ,KEY_MODE },/* SOURCE */ - {0x0200 ,KEY_POWER2 },/* POWER */ - {0x0205 ,KEY_1 },/* 1 */ - {0x0206 ,KEY_2 },/* 2 */ - {0x0207 ,KEY_3 },/* 3 */ - {0x0209 ,KEY_4 },/* 4 */ - {0x020a ,KEY_5 },/* 5 */ - {0x020b ,KEY_6 },/* 6 */ - {0x020d ,KEY_7 },/* 7 */ - {0x020e ,KEY_8 },/* 8 */ - {0x020f ,KEY_9 },/* 9 */ - {0x0212 ,KEY_LEFT },/* L / DISPLAY */ - {0x0211 ,KEY_0 },/* 0 */ - {0x0213 ,KEY_RIGHT },/* R / CH RTN */ - {0x0217 ,KEY_CAMERA },/* SNAP SHOT */ - {0x0210 ,KEY_LAST },/* 16-CH PREV */ - {0x021e ,KEY_VOLUMEDOWN },/* VOL DOWN */ - {0x020c ,KEY_ZOOM },/* FULL SCREEN */ - {0x021f ,KEY_VOLUMEUP },/* VOL UP */ - {0x0214 ,KEY_MUTE },/* MUTE */ - {0x0208 ,KEY_AUDIO },/* AUDIO */ - {0x0219 ,KEY_RECORD },/* RECORD */ - {0x0218 ,KEY_PLAY },/* PLAY */ - {0x021b ,KEY_STOP },/* STOP */ - {0x021a ,KEY_PLAYPAUSE },/* TIMESHIFT / PAUSE */ - {0x021d ,KEY_BACK },/* << / RED */ - {0x021c ,KEY_FORWARD },/* >> / YELLOW */ - {0x0203 ,KEY_TEXT },/* TELETEXT */ - {0x0204 ,KEY_EPG },/* EPG */ - {0x0215 ,KEY_MENU },/* MENU */ - - {0x0303 ,KEY_CHANNELUP },/* CH UP */ - {0x0302 ,KEY_CHANNELDOWN },/* CH DOWN */ - {0x0301 ,KEY_FIRST },/* |<< / GREEN */ - {0x0300 ,KEY_LAST },/* >>| / BLUE */ - -}; - -static int a800_rc_query (struct dvb_usb_device *d,u32 *event,int *state) +static int a800_rc_query (struct dvb_usb_device *d) { -int ret; +int ret =0 ;u8 *key =kmalloc (5 ,GFP_KERNEL );if (!key)return -ENOMEM ;
@@ -90,11 +51,12 @@ static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state) goto out; } -/* call the universal NEC remote processor, to find out the key's state and event */ -dvb_usb_nec_rc_key_to_event (d,key,event,state); -if (key[0 ] !=0 ) -deb_rc ("key: %*ph\n" ,5 , key); - ret =0 ; +/* Note that extended nec and nec32 are dropped */ +if (key[0 ] ==1 ) +rc_keydown (d->rc_dev,RC_PROTO_NEC , +RC_SCANCODE_NEC (key[1 ], key[3 ]),0 ); +else if (key[0 ] ==2 ) +rc_repeat (d->rc_dev); out:kfree (key);return ret;
@@ -157,11 +119,12 @@ static struct dvb_usb_device_properties a800_properties = { .power_ctrl = a800_power_ctrl, .identify_state = a800_identify_state, - .rc.legacy = { - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_map_table = rc_map_a800_table, - .rc_map_size = ARRAY_SIZE(rc_map_a800_table), - .rc_query = a800_rc_query, + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_AVERMEDIA_M135A, + .module_name = KBUILD_MODNAME, + .rc_query = a800_rc_query, + .allowed_protos = RC_PROTO_BIT_NEC, }, .i2c_algo = &dibusb_i2c_algo,
Signature · 1 line
2.13.5
Sean Young
maintainerPATCH 3/7 media: rc: avermedia keymap for a800
In reply to Sean YoungThe keymap is missing one key, and correct another.
--- drivers/media/rc/keymaps/rc-avermedia-m135a.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/media/rc/keymaps/rc-avermedia-m135a.c +2 -1
@@ -43,7 +43,8 @@ static struct rc_map_table avermedia_m135a[] = { { 0x0213, KEY_RIGHT }, /* -> or L */ { 0x0212, KEY_LEFT }, /* <- or R */ - { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */ + { 0x0215, KEY_MENU }, + { 0x0217, KEY_CAMERA }, /* Capturar Imagem or Snapshot */ { 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */ { 0x0303, KEY_CHANNELUP },
Signature · 1 line
2.13.5
Sean Young
maintainerPATCH 4/7 media: rc: ensure that protocols are enabled for scancode drivers
In reply to Sean Youngrc scancode drivers without change_protocol should have all protocols enabled at all time. This was only true for cec and ir-kbd-i2c.
--- drivers/media/cec/cec-core.c | 1 - drivers/media/i2c/ir-kbd-i2c.c | 1 - drivers/media/rc/rc-main.c | 3 +++ 3 files changed, 3 insertions(+), 2 deletions(-)
drivers/media/cec/cec-core.c +0 -1
@@ -277,7 +277,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, adap->rc->input_id.version =1 ; adap->rc->driver_name =CEC_NAME ; adap->rc->allowed_protocols =RC_PROTO_BIT_CEC ; - adap->rc->enabled_protocols =RC_PROTO_BIT_CEC ; adap->rc->priv = adap; adap->rc->map_name =RC_MAP_CEC ; adap->rc->timeout =MS_TO_NS (100 );
drivers/media/i2c/ir-kbd-i2c.c +0 -1
@@ -460,7 +460,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)*/ rc->map_name = ir->ir_codes; rc->allowed_protocols = rc_proto; - rc->enabled_protocols = rc_proto;if (!rc->driver_name) rc->driver_name =MODULE_NAME ;
drivers/media/rc/rc-main.c +3 -0
@@ -1638,6 +1638,9 @@ static int rc_prepare_rx_device(struct rc_dev *dev) rc_proto =BIT_ULL (rc_map->rc_proto); +if (dev->driver_type ==RC_DRIVER_SCANCODE && !dev->change_protocol) + dev->enabled_protocols = dev->allowed_protocols; +if (dev->change_protocol) { rc = dev->change_protocol (dev, &rc_proto);if (rc <0 )
Signature · 1 line
2.13.5
Sean Young
maintainerPATCH 5/7 media: rc: dvb: use dvb device name for rc device
In reply to Sean Young"IR-receiver inside an USB DVB receiver" is not descriptive and we have a proper name available.
--- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/usb/dvb-usb/dvb-usb-remote.c +1 -1
@@ -279,7 +279,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) dev->change_protocol = d->props.rc.core.change_protocol; dev->allowed_protocols = d->props.rc.core.allowed_protos;usb_to_input_id (d->udev, &dev->input_id); - dev->device_name ="IR-receiver inside an USB DVB receiver" ; + dev->device_name = d->desc->name; dev->input_phys = d->rc_phys; dev->dev.parent = &d->udev->dev; dev->priv = d;
Signature · 1 line
2.13.5
Sean Young
maintainerPATCH 6/7 media: rc: if protocols can't be changed, don't be writable
In reply to Sean YoungIf the protocols of an rc device cannot be changed, ensure the sysfs file is not writable.
This makes it possible to detect this from userspace, so ir-keytable can deal with case without giving an error.
--- drivers/media/rc/rc-main.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)
drivers/media/rc/rc-main.c +21 -7
@@ -1487,7 +1487,10 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)/* * Static device attribute struct with the sysfs attributes for IR's */ -static DEVICE_ATTR(protocols, 0644, show_protocols, store_protocols); +static struct device_attribute dev_attr_ro_protocols = +__ATTR (protocols,0444 , show_protocols, store_protocols); +static struct device_attribute dev_attr_rw_protocols = +__ATTR (protocols,0644 , show_protocols,NULL ); static DEVICE_ATTR(wakeup_protocols, 0644, show_wakeup_protocols, store_wakeup_protocols); static RC_FILTER_ATTR(filter, S_IRUGO|S_IWUSR,
@@ -1499,13 +1502,22 @@ static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR, static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR, show_filter, store_filter, RC_FILTER_WAKEUP, true); -static struct attribute *rc_dev_protocol_attrs[] = { - &dev_attr_protocols.attr, +static struct attribute *rc_dev_rw_protocol_attrs[] = { + &dev_attr_rw_protocols.attr,NULL , }; -static const struct attribute_group rc_dev_protocol_attr_grp = { - .attrs = rc_dev_protocol_attrs, +static const struct attribute_group rc_dev_rw_protocol_attr_grp = { + .attrs = rc_dev_rw_protocol_attrs, +}; + +static struct attribute *rc_dev_ro_protocol_attrs[] = { + &dev_attr_ro_protocols.attr, +NULL , +}; + +static const struct attribute_group rc_dev_ro_protocol_attr_grp = { + .attrs = rc_dev_ro_protocol_attrs, };static struct attribute *rc_dev_filter_attrs[] = {
@@ -1732,8 +1744,10 @@ int rc_register_device(struct rc_dev *dev)dev_set_drvdata (&dev->dev, dev); dev->dev.groups = dev->sysfs_groups; -if (dev->driver_type !=RC_DRIVER_IR_RAW_TX ) - dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp; +if (dev->driver_type ==RC_DRIVER_SCANCODE && !dev->change_protocol) + dev->sysfs_groups[attr++] = &rc_dev_ro_protocol_attr_grp; +else if (dev->driver_type !=RC_DRIVER_IR_RAW_TX ) + dev->sysfs_groups[attr++] = &rc_dev_rw_protocol_attr_grp;if (dev->s_filter) dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp;if (dev->s_wakeup_filter)
Signature · 1 line
2.13.5
Sean Young
maintainerPATCH 7/7 media: rc: include device name in rc udev event
In reply to Sean YoungThis name is also stored in the input's device name, but that is not available in TX only hardware (no input device).
--- drivers/media/rc/rc-main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/media/rc/rc-main.c +2 -0
@@ -1480,6 +1480,8 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)ADD_HOTPLUG_VAR ("NAME=%s" , dev->rc_map.name);if (dev->driver_name)ADD_HOTPLUG_VAR ("DRV_NAME=%s" , dev->driver_name); +if (dev->device_name) +ADD_HOTPLUG_VAR ("DEV_NAME=%s" , dev->device_name);return 0 ; }
Signature · 1 line
2.13.5