diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
31 files changed, 920 insertions, 931 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 553b48ac1919..fdc19bba2128 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -1,6 +1,6 @@ config DVB_USB tristate "Support for various USB DVB devices" - depends on DVB_CORE && USB && I2C && INPUT + depends on DVB_CORE && USB && I2C && IR_CORE help By enabling this you will be able to choose the various supported USB1.1 and USB2.0 DVB devices. diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index b6cbb1dfc5f1..a5c363727133 100644 --- a/drivers/media/dvb/dvb-usb/a800.c +++ b/drivers/media/dvb/dvb-usb/a800.c @@ -37,7 +37,7 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr return 0; } -static struct dvb_usb_rc_key ir_codes_a800_table[] = { +static struct ir_scancode ir_codes_a800_table[] = { { 0x0201, KEY_PROG1 }, /* SOURCE */ { 0x0200, KEY_POWER }, /* POWER */ { 0x0205, KEY_1 }, /* 1 */ @@ -146,10 +146,12 @@ static struct dvb_usb_device_properties a800_properties = { .power_ctrl = a800_power_ctrl, .identify_state = a800_identify_state, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_a800_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_a800_table), - .rc_query = a800_rc_query, + .rc.legacy = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = ir_codes_a800_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_a800_table), + .rc_query = a800_rc_query, + }, .i2c_algo = &dibusb_i2c_algo, diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c index b41fa873b04d..696207fe37ec 100644 --- a/drivers/media/dvb/dvb-usb/af9005-remote.c +++ b/drivers/media/dvb/dvb-usb/af9005-remote.c @@ -33,7 +33,7 @@ MODULE_PARM_DESC(debug, #define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args) -struct dvb_usb_rc_key ir_codes_af9005_table[] = { +struct ir_scancode ir_codes_af9005_table[] = { {0x01b7, KEY_POWER}, {0x01a7, KEY_VOLUMEUP}, @@ -133,7 +133,7 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event, for (i = 0; i < ir_codes_af9005_table_size; i++) { if (rc5_custom(&ir_codes_af9005_table[i]) == cust && rc5_data(&ir_codes_af9005_table[i]) == dat) { - *event = ir_codes_af9005_table[i].event; + *event = ir_codes_af9005_table[i].keycode; *state = REMOTE_KEY_PRESSED; deb_decode ("key pressed, event %x\n", *event); diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c index cfd6107d5349..8ecba8848bcf 100644 --- a/drivers/media/dvb/dvb-usb/af9005.c +++ b/drivers/media/dvb/dvb-usb/af9005.c @@ -54,50 +54,6 @@ struct af9005_device_state { int led_state; }; -static int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, - u8 *rbuf, u16 rlen, int delay_ms) -{ - int actlen, ret = -ENOMEM; - - if (wbuf == NULL || wlen == 0) - return -EINVAL; - - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) - return ret; - - deb_xfer(">>> "); - debug_dump(wbuf, wlen, deb_xfer); - - ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev, - 2), wbuf, wlen, - &actlen, 2000); - - if (ret) - err("bulk message failed: %d (%d/%d)", ret, wlen, actlen); - else - ret = actlen != wlen ? -1 : 0; - - /* an answer is expected, and no error before */ - if (!ret && rbuf && rlen) { - if (delay_ms) - msleep(delay_ms); - - ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, - 0x01), rbuf, - rlen, &actlen, 2000); - - if (ret) - err("recv bulk message failed: %d", ret); - else { - deb_xfer("<<< "); - debug_dump(rbuf, actlen, deb_xfer); - } - } - - mutex_unlock(&d->usb_mutex); - return ret; -} - static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg, int readwrite, int type, u8 * values, int len) { @@ -146,7 +102,7 @@ static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg, obuf[8] = values[0]; obuf[7] = command; - ret = af9005_usb_generic_rw(d, obuf, 16, ibuf, 17, 0); + ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 17, 0); if (ret) return ret; @@ -534,7 +490,7 @@ int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf, buf[6] = wlen; for (i = 0; i < wlen; i++) buf[7 + i] = wbuf[i]; - ret = af9005_usb_generic_rw(d, buf, wlen + 7, ibuf, rlen + 7, 0); + ret = dvb_usb_generic_rw(d, buf, wlen + 7, ibuf, rlen + 7, 0); if (ret) return ret; if (ibuf[2] != 0x27) { @@ -581,7 +537,7 @@ int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values, obuf[6] = len; obuf[7] = address; - ret = af9005_usb_generic_rw(d, obuf, 16, ibuf, 14, 0); + ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 14, 0); if (ret) return ret; if (ibuf[2] != 0x2b) { @@ -882,7 +838,7 @@ static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state) obuf[2] = 0x40; /* read remote */ obuf[3] = 1; /* rest of packet length */ obuf[4] = st->sequence++; /* sequence number */ - ret = af9005_usb_generic_rw(d, obuf, 5, ibuf, 256, 0); + ret = dvb_usb_generic_rw(d, obuf, 5, ibuf, 256, 0); if (ret) { err("rc query failed"); return ret; @@ -1069,10 +1025,15 @@ static struct dvb_usb_device_properties af9005_properties = { .i2c_algo = &af9005_i2c_algo, - .rc_interval = 200, - .rc_key_map = NULL, - .rc_key_map_size = 0, - .rc_query = af9005_rc_query, + .rc.legacy = { + .rc_interval = 200, + .rc_key_map = NULL, + .rc_key_map_size = 0, + .rc_query = af9005_rc_query, + }, + + .generic_bulk_ctrl_endpoint = 2, + .generic_bulk_ctrl_endpoint_response = 1, .num_device_descs = 3, .devices = { @@ -1113,10 +1074,10 @@ static int __init af9005_usb_module_init(void) rc_keys_size = symbol_request(ir_codes_af9005_table_size); if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { err("af9005_rc_decode function not found, disabling remote"); - af9005_properties.rc_query = NULL; + af9005_properties.rc.legacy.rc_query = NULL; } else { - af9005_properties.rc_key_map = rc_keys; - af9005_properties.rc_key_map_size = *rc_keys_size; + af9005_properties.rc.legacy.rc_key_map = rc_keys; + af9005_properties.rc.legacy.rc_key_map_size = *rc_keys_size; } return 0; diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h index 088e7083a39b..3c1fbd1c5d60 100644 --- a/drivers/media/dvb/dvb-usb/af9005.h +++ b/drivers/media/dvb/dvb-usb/af9005.h @@ -3490,7 +3490,7 @@ extern u8 regmask[8]; /* remote control decoder */ extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event, int *state); -extern struct dvb_usb_rc_key ir_codes_af9005_table[]; +extern struct ir_scancode ir_codes_af9005_table[]; extern int ir_codes_af9005_table_size; #endif diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 66c7c3ea7990..ea1ed3b4592a 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -735,7 +735,7 @@ error: struct af9015_setup { unsigned int id; - struct dvb_usb_rc_key *rc_key_map; + struct ir_scancode *rc_key_map; unsigned int rc_key_map_size; u8 *ir_table; unsigned int ir_table_size; @@ -847,8 +847,8 @@ static void af9015_set_remote_config(struct usb_device *udev, } if (table) { - props->rc_key_map = table->rc_key_map; - props->rc_key_map_size = table->rc_key_map_size; + props->rc.legacy.rc_key_map = table->rc_key_map; + props->rc.legacy.rc_key_map_size = table->rc_key_map_size; af9015_config.ir_table = table->ir_table; af9015_config.ir_table_size = table->ir_table_size; } @@ -878,8 +878,8 @@ static int af9015_read_config(struct usb_device *udev) deb_info("%s: IR mode:%d\n", __func__, val); for (i = 0; i < af9015_properties_count; i++) { if (val == AF9015_IR_MODE_DISABLED) { - af9015_properties[i].rc_key_map = NULL; - af9015_properties[i].rc_key_map_size = 0; + af9015_properties[i].rc.legacy.rc_key_map = NULL; + af9015_properties[i].rc.legacy.rc_key_map_size = 0; } else af9015_set_remote_config(udev, &af9015_properties[i]); } @@ -1063,7 +1063,7 @@ static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { u8 buf[8]; struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf}; - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; int i, ret; memset(buf, 0, sizeof(buf)); @@ -1075,10 +1075,10 @@ static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state) *event = 0; *state = REMOTE_NO_KEY_PRESSED; - for (i = 0; i < d->props.rc_key_map_size; i++) { + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { if (!buf[1] && rc5_custom(&keymap[i]) == buf[0] && rc5_data(&keymap[i]) == buf[2]) { - *event = keymap[i].event; + *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; break; } @@ -1299,6 +1299,7 @@ static struct usb_device_id af9015_usb_table[] = { {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)}, /* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1353,8 +1354,10 @@ static struct dvb_usb_device_properties af9015_properties[] = { .identify_state = af9015_identify_state, - .rc_query = af9015_rc_query, - .rc_interval = 150, + .rc.legacy = { + .rc_query = af9015_rc_query, + .rc_interval = 150, + }, .i2c_algo = &af9015_i2c_algo, @@ -1460,8 +1463,10 @@ static struct dvb_usb_device_properties af9015_properties[] = { .identify_state = af9015_identify_state, - .rc_query = af9015_rc_query, - .rc_interval = 150, + .rc.legacy = { + .rc_query = af9015_rc_query, + .rc_interval = 150, + }, .i2c_algo = &af9015_i2c_algo, @@ -1567,12 +1572,14 @@ static struct dvb_usb_device_properties af9015_properties[] = { .identify_state = af9015_identify_state, - .rc_query = af9015_rc_query, - .rc_interval = 150, + .rc.legacy = { + .rc_query = af9015_rc_query, + .rc_interval = 150, + }, .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 8, /* max 9 */ + .num_device_descs = 9, /* max 9 */ .devices = { { .name = "AverMedia AVerTV Volar GPS 805 (A805)", @@ -1617,6 +1624,11 @@ static struct dvb_usb_device_properties af9015_properties[] = { .cold_ids = {&af9015_usb_table[30], NULL}, .warm_ids = {NULL}, }, + { + .name = "AverMedia AVerTV Volar M (A815Mac)", + .cold_ids = {&af9015_usb_table[32], NULL}, + .warm_ids = {NULL}, + }, } }, }; diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index 63b2a4907b7e..c8e9349742ee 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -123,7 +123,7 @@ enum af9015_remote { /* LeadTek - Y04G0051 */ /* Leadtek WinFast DTV Dongle Gold */ -static struct dvb_usb_rc_key ir_codes_af9015_table_leadtek[] = { +static struct ir_scancode ir_codes_af9015_table_leadtek[] = { { 0x001e, KEY_1 }, { 0x001f, KEY_2 }, { 0x0020, KEY_3 }, @@ -227,7 +227,7 @@ static u8 af9015_ir_table_leadtek[] = { }; /* TwinHan AzureWave AD-TU700(704J) */ -static struct dvb_usb_rc_key ir_codes_af9015_table_twinhan[] = { +static struct ir_scancode ir_codes_af9015_table_twinhan[] = { { 0x053f, KEY_POWER }, { 0x0019, KEY_FAVORITES }, /* Favorite List */ { 0x0004, KEY_TEXT }, /* Teletext */ @@ -338,7 +338,7 @@ static u8 af9015_ir_table_twinhan[] = { }; /* A-Link DTU(m) */ -static struct dvb_usb_rc_key ir_codes_af9015_table_a_link[] = { +static struct ir_scancode ir_codes_af9015_table_a_link[] = { { 0x001e, KEY_1 }, { 0x001f, KEY_2 }, { 0x0020, KEY_3 }, @@ -381,7 +381,7 @@ static u8 af9015_ir_table_a_link[] = { }; /* MSI DIGIVOX mini II V3.0 */ -static struct dvb_usb_rc_key ir_codes_af9015_table_msi[] = { +static struct ir_scancode ir_codes_af9015_table_msi[] = { { 0x001e, KEY_1 }, { 0x001f, KEY_2 }, { 0x0020, KEY_3 }, @@ -424,7 +424,7 @@ static u8 af9015_ir_table_msi[] = { }; /* MYGICTV U718 */ -static struct dvb_usb_rc_key ir_codes_af9015_table_mygictv[] = { +static struct ir_scancode ir_codes_af9015_table_mygictv[] = { { 0x003d, KEY_SWITCHVIDEOMODE }, /* TV / AV */ { 0x0545, KEY_POWER }, @@ -550,7 +550,7 @@ static u8 af9015_ir_table_kworld[] = { }; /* AverMedia Volar X */ -static struct dvb_usb_rc_key ir_codes_af9015_table_avermedia[] = { +static struct ir_scancode ir_codes_af9015_table_avermedia[] = { { 0x053d, KEY_PROG1 }, /* SOURCE */ { 0x0512, KEY_POWER }, /* POWER */ { 0x051e, KEY_1 }, /* 1 */ @@ -656,7 +656,7 @@ static u8 af9015_ir_table_avermedia_ks[] = { }; /* Digittrade DVB-T USB Stick */ -static struct dvb_usb_rc_key ir_codes_af9015_table_digittrade[] = { +static struct ir_scancode ir_codes_af9015_table_digittrade[] = { { 0x010f, KEY_LAST }, /* RETURN */ { 0x0517, KEY_TEXT }, /* TELETEXT */ { 0x0108, KEY_EPG }, /* EPG */ @@ -719,7 +719,7 @@ static u8 af9015_ir_table_digittrade[] = { }; /* TREKSTOR DVB-T USB Stick */ -static struct dvb_usb_rc_key ir_codes_af9015_table_trekstor[] = { +static struct ir_scancode ir_codes_af9015_table_trekstor[] = { { 0x0704, KEY_AGAIN }, /* Home */ { 0x0705, KEY_MUTE }, /* Mute */ { 0x0706, KEY_UP }, /* Up */ @@ -782,7 +782,7 @@ static u8 af9015_ir_table_trekstor[] = { }; /* MSI DIGIVOX mini III */ -static struct dvb_usb_rc_key ir_codes_af9015_table_msi_digivox_iii[] = { +static struct ir_scancode ir_codes_af9015_table_msi_digivox_iii[] = { { 0x0713, KEY_POWER }, /* [red power button] */ { 0x073b, KEY_VIDEO }, /* Source */ { 0x073e, KEY_ZOOM }, /* Zoom */ diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index faca1ad88a67..4685259e1614 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -377,7 +377,7 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { u8 buf[] = {CMD_GET_IR_CODE}; - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; u8 ircode[2]; int i, ret; @@ -388,10 +388,10 @@ static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state) *event = 0; *state = REMOTE_NO_KEY_PRESSED; - for (i = 0; i < d->props.rc_key_map_size; i++) { + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { if (rc5_custom(&keymap[i]) == ircode[0] && rc5_data(&keymap[i]) == ircode[1]) { - *event = keymap[i].event; + *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; return 0; } @@ -399,7 +399,7 @@ static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state) return 0; } -static struct dvb_usb_rc_key ir_codes_anysee_table[] = { +static struct ir_scancode ir_codes_anysee_table[] = { { 0x0100, KEY_0 }, { 0x0101, KEY_1 }, { 0x0102, KEY_2 }, @@ -463,6 +463,11 @@ static int anysee_probe(struct usb_interface *intf, if (intf->num_altsetting < 1) return -ENODEV; + /* + * Anysee is always warm (its USB-bridge, Cypress FX2, uploads + * firmware from eeprom). If dvb_usb_device_init() succeeds that + * means d is a valid pointer. + */ ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d, adapter_nr); if (ret) @@ -479,10 +484,7 @@ static int anysee_probe(struct usb_interface *intf, if (ret) return ret; - if (d) - ret = anysee_init(d); - - return ret; + return anysee_init(d); } static struct usb_device_id anysee_table[] = { @@ -518,10 +520,12 @@ static struct dvb_usb_device_properties anysee_properties = { } }, - .rc_key_map = ir_codes_anysee_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_anysee_table), - .rc_query = anysee_rc_query, - .rc_interval = 200, /* windows driver uses 500ms */ + .rc.legacy = { + .rc_key_map = ir_codes_anysee_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_anysee_table), + .rc_query = anysee_rc_query, + .rc_interval = 200, /* windows driver uses 500ms */ + }, .i2c_algo = &anysee_i2c_algo, diff --git a/drivers/media/dvb/dvb-usb/az6027.c b/drivers/media/dvb/dvb-usb/az6027.c index 6681ac1c56e3..62c58288469f 100644 --- a/drivers/media/dvb/dvb-usb/az6027.c +++ b/drivers/media/dvb/dvb-usb/az6027.c @@ -386,7 +386,7 @@ static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) } /* keys for the enclosed remote control */ -static struct dvb_usb_rc_key ir_codes_az6027_table[] = { +static struct ir_scancode ir_codes_az6027_table[] = { { 0x01, KEY_1 }, { 0x02, KEY_2 }, }; @@ -1125,10 +1125,13 @@ static struct dvb_usb_device_properties az6027_properties = { .power_ctrl = az6027_power_ctrl, .read_mac_address = az6027_read_mac_addr, */ - .rc_key_map = ir_codes_az6027_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_az6027_table), - .rc_interval = 400, - .rc_query = az6027_rc_query, + .rc.legacy = { + .rc_key_map = ir_codes_az6027_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_az6027_table), + .rc_interval = 400, + .rc_query = az6027_rc_query, + }, + .i2c_algo = &az6027_i2c_algo, .num_device_descs = 5, diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c index 5a9c14bdc980..4f5aa83fc1fc 100644 --- a/drivers/media/dvb/dvb-usb/cinergyT2-core.c +++ b/drivers/media/dvb/dvb-usb/cinergyT2-core.c @@ -84,7 +84,7 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) return 0; } -static struct dvb_usb_rc_key ir_codes_cinergyt2_table[] = { +static struct ir_scancode ir_codes_cinergyt2_table[] = { { 0x0401, KEY_POWER }, { 0x0402, KEY_1 }, { 0x0403, KEY_2 }, @@ -217,10 +217,12 @@ static struct dvb_usb_device_properties cinergyt2_properties = { .power_ctrl = cinergyt2_power_ctrl, - .rc_interval = 50, - .rc_key_map = ir_codes_cinergyt2_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_cinergyt2_table), - .rc_query = cinergyt2_rc_query, + .rc.legacy = { + .rc_interval = 50, + .rc_key_map = ir_codes_cinergyt2_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_cinergyt2_table), + .rc_query = cinergyt2_rc_query, + }, .generic_bulk_ctrl_endpoint = 1, diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 11e9e85dac86..cd9f362c37b2 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -385,7 +385,7 @@ static int cxusb_d680_dmb_streaming_ctrl( static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; u8 ircode[4]; int i; @@ -394,10 +394,10 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) *event = 0; *state = REMOTE_NO_KEY_PRESSED; - for (i = 0; i < d->props.rc_key_map_size; i++) { + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { if (rc5_custom(&keymap[i]) == ircode[2] && rc5_data(&keymap[i]) == ircode[3]) { - *event = keymap[i].event; + *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; return 0; @@ -410,7 +410,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; u8 ircode[4]; int i; struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD, @@ -422,10 +422,10 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event, if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1) return 0; - for (i = 0; i < d->props.rc_key_map_size; i++) { + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { if (rc5_custom(&keymap[i]) == ircode[1] && rc5_data(&keymap[i]) == ircode[2]) { - *event = keymap[i].event; + *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; return 0; @@ -438,7 +438,7 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event, static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; u8 ircode[2]; int i; @@ -448,10 +448,10 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event, if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0) return 0; - for (i = 0; i < d->props.rc_key_map_size; i++) { + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { if (rc5_custom(&keymap[i]) == ircode[0] && rc5_data(&keymap[i]) == ircode[1]) { - *event = keymap[i].event; + *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; return 0; @@ -461,7 +461,7 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event, return 0; } -static struct dvb_usb_rc_key ir_codes_dvico_mce_table[] = { +static struct ir_scancode ir_codes_dvico_mce_table[] = { { 0xfe02, KEY_TV }, { 0xfe0e, KEY_MP3 }, { 0xfe1a, KEY_DVD }, @@ -509,7 +509,7 @@ static struct dvb_usb_rc_key ir_codes_dvico_mce_table[] = { { 0xfe4e, KEY_POWER }, }; -static struct dvb_usb_rc_key ir_codes_dvico_portable_table[] = { +static struct ir_scancode ir_codes_dvico_portable_table[] = { { 0xfc02, KEY_SETUP }, /* Profile */ { 0xfc43, KEY_POWER2 }, { 0xfc06, KEY_EPG }, @@ -548,7 +548,7 @@ static struct dvb_usb_rc_key ir_codes_dvico_portable_table[] = { { 0xfc00, KEY_UNKNOWN }, /* HD */ }; -static struct dvb_usb_rc_key ir_codes_d680_dmb_table[] = { +static struct ir_scancode ir_codes_d680_dmb_table[] = { { 0x0038, KEY_UNKNOWN }, /* TV/AV */ { 0x080c, KEY_ZOOM }, { 0x0800, KEY_0 }, @@ -923,7 +923,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) return -EIO; /* try to determine if there is no IR decoder on the I2C bus */ - for (i = 0; adap->dev->props.rc_key_map != NULL && i < 5; i++) { + for (i = 0; adap->dev->props.rc.legacy.rc_key_map != NULL && i < 5; i++) { msleep(20); if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1) goto no_IR; @@ -931,7 +931,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) continue; if (ircode[2] + ircode[3] != 0xff) { no_IR: - adap->dev->props.rc_key_map = NULL; + adap->dev->props.rc.legacy.rc_key_map = NULL; info("No IR receiver detected on this device."); break; } @@ -1451,10 +1451,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = { .i2c_algo = &cxusb_i2c_algo, - .rc_interval = 100, - .rc_key_map = ir_codes_dvico_portable_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table), - .rc_query = cxusb_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_dvico_portable_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table), + .rc_query = cxusb_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x01, @@ -1502,10 +1504,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = { .i2c_algo = &cxusb_i2c_algo, - .rc_interval = 150, - .rc_key_map = ir_codes_dvico_mce_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table), - .rc_query = cxusb_rc_query, + .rc.legacy = { + .rc_interval = 150, + .rc_key_map = ir_codes_dvico_mce_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table), + .rc_query = cxusb_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x01, @@ -1561,10 +1565,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { .i2c_algo = &cxusb_i2c_algo, - .rc_interval = 100, - .rc_key_map = ir_codes_dvico_portable_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table), - .rc_query = cxusb_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_dvico_portable_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table), + .rc_query = cxusb_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x01, .num_device_descs = 1, @@ -1611,10 +1617,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = { .i2c_algo = &cxusb_i2c_algo, - .rc_interval = 100, - .rc_key_map = ir_codes_dvico_portable_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table), - .rc_query = cxusb_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_dvico_portable_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table), + .rc_query = cxusb_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x01, @@ -1660,10 +1668,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = { .generic_bulk_ctrl_endpoint = 0x01, - .rc_interval = 100, - .rc_key_map = ir_codes_dvico_mce_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table), - .rc_query = cxusb_bluebird2_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_dvico_mce_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table), + .rc_query = cxusb_bluebird2_rc_query, + }, .num_device_descs = 1, .devices = { @@ -1708,10 +1718,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = { .generic_bulk_ctrl_endpoint = 0x01, - .rc_interval = 100, - .rc_key_map = ir_codes_dvico_portable_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table), - .rc_query = cxusb_bluebird2_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_dvico_portable_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table), + .rc_query = cxusb_bluebird2_rc_query, + }, .num_device_descs = 1, .devices = { @@ -1758,10 +1770,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope .generic_bulk_ctrl_endpoint = 0x01, - .rc_interval = 100, - .rc_key_map = ir_codes_dvico_portable_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table), - .rc_query = cxusb_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_dvico_portable_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table), + .rc_query = cxusb_rc_query, + }, .num_device_descs = 1, .devices = { @@ -1849,10 +1863,12 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { .generic_bulk_ctrl_endpoint = 0x01, - .rc_interval = 100, - .rc_key_map = ir_codes_dvico_mce_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table), - .rc_query = cxusb_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_dvico_mce_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table), + .rc_query = cxusb_rc_query, + }, .num_device_descs = 1, .devices = { @@ -1897,10 +1913,12 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { .generic_bulk_ctrl_endpoint = 0x01, - .rc_interval = 100, - .rc_key_map = ir_codes_d680_dmb_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table), - .rc_query = cxusb_d680_dmb_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_d680_dmb_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table), + .rc_query = cxusb_d680_dmb_rc_query, + }, .num_device_descs = 1, .devices = { @@ -1946,10 +1964,12 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { .generic_bulk_ctrl_endpoint = 0x01, - .rc_interval = 100, - .rc_key_map = ir_codes_d680_dmb_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table), - .rc_query = cxusb_d680_dmb_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_d680_dmb_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table), + .rc_query = cxusb_d680_dmb_rc_query, + }, .num_device_descs = 1, .devices = { diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index 83fc24a6c31a..c2c9d236ec7e 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h @@ -60,6 +60,7 @@ extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); extern struct i2c_algorithm dib0700_i2c_algo; extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold); +extern int dib0700_change_protocol(void *priv, u64 ir_type); extern int dib0700_device_count; extern int dvb_usb_dib0700_ir_proto; diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index 4f961d2d1817..fe818348b8a3 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -13,10 +13,6 @@ int dvb_usb_dib0700_debug; module_param_named(debug,dvb_usb_dib0700_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS); -int dvb_usb_dib0700_ir_proto = 1; -module_param(dvb_usb_dib0700_ir_proto, int, 0644); -MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6)."); - static int nb_packet_buffer_size = 21; module_param(nb_packet_buffer_size, int, 0644); MODULE_PARM_DESC(nb_packet_buffer_size, @@ -53,7 +49,7 @@ static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen) int status; deb_data(">>> "); - debug_dump(tx,txlen,deb_data); + debug_dump(tx, txlen, deb_data); status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0), tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen, @@ -98,7 +94,7 @@ int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen deb_info("ep 0 read error (status = %d)\n",status); deb_data("<<< "); - debug_dump(rx,rxlen,deb_data); + debug_dump(rx, rxlen, deb_data); return status; /* length in case of success */ } @@ -106,28 +102,29 @@ int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val) { u8 buf[3] = { REQUEST_SET_GPIO, gpio, ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6) }; - return dib0700_ctrl_wr(d,buf,3); + return dib0700_ctrl_wr(d, buf, sizeof(buf)); } static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets) { - struct dib0700_state *st = d->priv; - u8 b[3]; - int ret; - - if (st->fw_version >= 0x10201) { - b[0] = REQUEST_SET_USB_XFER_LEN; - b[1] = (nb_ts_packets >> 8)&0xff; - b[2] = nb_ts_packets & 0xff; - - deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets); - - ret = dib0700_ctrl_wr(d, b, 3); - } else { - deb_info("this firmware does not allow to change the USB xfer len\n"); - ret = -EIO; - } - return ret; + struct dib0700_state *st = d->priv; + u8 b[3]; + int ret; + + if (st->fw_version >= 0x10201) { + b[0] = REQUEST_SET_USB_XFER_LEN; + b[1] = (nb_ts_packets >> 8) & 0xff; + b[2] = nb_ts_packets & 0xff; + + deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets); + + ret = dib0700_ctrl_wr(d, b, sizeof(b)); + } else { + deb_info("this firmware does not allow to change the USB xfer len\n"); + ret = -EIO; + } + + return ret; } /* @@ -178,7 +175,8 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, value = ((en_start << 7) | (en_stop << 6) | (msg[i].len & 0x3F)) << 8 | i2c_dest; /* I2C ctrl + FE bus; */ - index = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30); + index = ((gen_mode << 6) & 0xC0) | + ((bus_mode << 4) & 0x30); result = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), @@ -198,11 +196,12 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, } else { /* Write request */ buf[0] = REQUEST_NEW_I2C_WRITE; - buf[1] = (msg[i].addr << 1); + buf[1] = msg[i].addr << 1; buf[2] = (en_start << 7) | (en_stop << 6) | (msg[i].len & 0x3F); /* I2C ctrl + FE bus; */ - buf[3] = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30); + buf[3] = ((gen_mode << 6) & 0xC0) | + ((bus_mode << 4) & 0x30); /* The Actual i2c payload */ memcpy(&buf[4], msg[i].buf, msg[i].len); @@ -240,7 +239,7 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, for (i = 0; i < num; i++) { /* fill in the address */ - buf[1] = (msg[i].addr << 1); + buf[1] = msg[i].addr << 1; /* fill the buffer */ memcpy(&buf[2], msg[i].buf, msg[i].len); @@ -368,7 +367,8 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw u8 buf[260]; while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) { - deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",hx.addr, hx.len, hx.chk); + deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n", + hx.addr, hx.len, hx.chk); buf[0] = hx.len; buf[1] = (hx.addr >> 8) & 0xff; @@ -408,16 +408,16 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, sizeof(b), USB_CTRL_GET_TIMEOUT); - fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; + fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; /* set the buffer size - DVB-USB is allocating URB buffers * only after the firwmare download was successful */ for (i = 0; i < dib0700_device_count; i++) { for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters; adap_num++) { - if (fw_version >= 0x10201) + if (fw_version >= 0x10201) { dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size; - else { + } else { /* for fw version older than 1.20.1, * the buffersize has to be n times 512 */ dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512; @@ -453,7 +453,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) if (st->disable_streaming_master_mode == 1) b[2] = 0x00; else - b[2] = (0x01 << 4); /* Master mode */ + b[2] = 0x01 << 4; /* Master mode */ b[3] = 0x00; @@ -466,11 +466,44 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) b[2] |= st->channel_state; - deb_info("data for streaming: %x %x\n",b[1],b[2]); + deb_info("data for streaming: %x %x\n", b[1], b[2]); return dib0700_ctrl_wr(adap->dev, b, 4); } +int dib0700_change_protocol(void *priv, u64 ir_type) +{ + struct dvb_usb_device *d = priv; + struct dib0700_state *st = d->priv; + u8 rc_setup[3] = { REQUEST_SET_RC, 0, 0 }; + int new_proto, ret; + + /* Set the IR mode */ + if (ir_type == IR_TYPE_RC5) + new_proto = 1; + else if (ir_type == IR_TYPE_NEC) + new_proto = 0; + else if (ir_type == IR_TYPE_RC6) { + if (st->fw_version < 0x10200) + return -EINVAL; + + new_proto = 2; + } else + return -EINVAL; + + rc_setup[1] = new_proto; + + ret = dib0700_ctrl_wr(d, rc_setup, sizeof(rc_setup)); + if (ret < 0) { + err("ir protocol setup failed"); + return ret; + } + + d->props.rc.core.protocol = ir_type; + + return ret; +} + /* Number of keypresses to ignore before start repeating */ #define RC_REPEAT_DELAY_V1_20 10 @@ -478,7 +511,13 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) struct dib0700_rc_response { u8 report_id; u8 data_state; - u16 system; + union { + u16 system16; + struct { + u8 system; + u8 not_system; + }; + }; u8 data; u8 not_data; }; @@ -487,14 +526,10 @@ struct dib0700_rc_response { static void dib0700_rc_urb_completion(struct urb *purb) { struct dvb_usb_device *d = purb->context; - struct dvb_usb_rc_key *keymap; struct dib0700_state *st; - struct dib0700_rc_response poll_reply; - u8 *buf; - int found = 0; - u32 event; - int state; - int i; + struct dib0700_rc_response *poll_reply; + u32 uninitialized_var(keycode); + u8 toggle; deb_info("%s()\n", __func__); if (d == NULL) @@ -506,9 +541,8 @@ static void dib0700_rc_urb_completion(struct urb *purb) return; } - keymap = d->props.rc_key_map; st = d->priv; - buf = (u8 *)purb->transfer_buffer; + poll_reply = purb->transfer_buffer; if (purb->status < 0) { deb_info("discontinuing polling\n"); @@ -521,104 +555,52 @@ static void dib0700_rc_urb_completion(struct urb *purb) goto resubmit; } - /* Set initial results in case we exit the function early */ - event = 0; - state = REMOTE_NO_KEY_PRESSED; - - deb_data("IR raw %02X %02X %02X %02X %02X %02X (len %d)\n", buf[0], - buf[1], buf[2], buf[3], buf[4], buf[5], purb->actual_length); + deb_data("IR ID = %02X state = %02X System = %02X %02X Cmd = %02X %02X (len %d)\n", + poll_reply->report_id, poll_reply->data_state, + poll_reply->system, poll_reply->not_system, + poll_reply->data, poll_reply->not_data, + purb->actual_length); - switch (dvb_usb_dib0700_ir_proto) { - case 0: - /* NEC Protocol */ - poll_reply.report_id = 0; - poll_reply.data_state = 1; - poll_reply.system = buf[2]; - poll_reply.data = buf[4]; - poll_reply.not_data = buf[5]; + switch (d->props.rc.core.protocol) { + case IR_TYPE_NEC: + toggle = 0; /* NEC protocol sends repeat code as 0 0 0 FF */ - if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00) - && (poll_reply.not_data == 0xff)) { - poll_reply.data_state = 2; + if ((poll_reply->system == 0x00) && (poll_reply->data == 0x00) + && (poll_reply->not_data == 0xff)) { + poll_reply->data_state = 2; break; } + + if ((poll_reply->system ^ poll_reply->not_system) != 0xff) { + deb_data("NEC extended protocol\n"); + /* NEC extended code - 24 bits */ + keycode = poll_reply->system16 << 8 | poll_reply->data; + } else { + deb_data("NEC normal protocol\n"); + /* normal NEC code - 16 bits */ + keycode = poll_reply->system << 8 | poll_reply->data; + } + break; default: + deb_data("RC5 protocol\n"); /* RC5 Protocol */ - poll_reply.report_id = buf[0]; - poll_reply.data_state = buf[1]; - poll_reply.system = (buf[2] << 8) | buf[3]; - poll_reply.data = buf[4]; - poll_reply.not_data = buf[5]; + toggle = poll_reply->report_id; + keycode = poll_reply->system16 << 8 | poll_reply->data; + break; } - if ((poll_reply.data + poll_reply.not_data) != 0xff) { + if ((poll_reply->data + poll_reply->not_data) != 0xff) { /* Key failed integrity check */ err("key failed integrity check: %04x %02x %02x", - poll_reply.system, - poll_reply.data, poll_reply.not_data); - goto resubmit; - } - - deb_data("rid=%02x ds=%02x sm=%04x d=%02x nd=%02x\n", - poll_reply.report_id, poll_reply.data_state, - poll_reply.system, poll_reply.data, poll_reply.not_data); - - /* Find the key in the map */ - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) && - rc5_data(&keymap[i]) == poll_reply.data) { - event = keymap[i].event; - found = 1; - break; - } - } - - if (found == 0) { - err("Unknown remote controller key: %04x %02x %02x", - poll_reply.system, poll_reply.data, poll_reply.not_data); - d->last_event = 0; + poll_reply->system, + poll_reply->data, poll_reply->not_data); goto resubmit; } - if (poll_reply.data_state == 1) { - /* New key hit */ - st->rc_counter = 0; - event = keymap[i].event; - state = REMOTE_KEY_PRESSED; - d->last_event = keymap[i].event; - } else if (poll_reply.data_state == 2) { - /* Key repeated */ - st->rc_counter++; - - /* prevents unwanted double hits */ - if (st->rc_counter > RC_REPEAT_DELAY_V1_20) { - event = d->last_event; - state = REMOTE_KEY_PRESSED; - st->rc_counter = RC_REPEAT_DELAY_V1_20; - } - } else { - err("Unknown data state [%d]", poll_reply.data_state); - } - - switch (state) { - case REMOTE_NO_KEY_PRESSED: - break; - case REMOTE_KEY_PRESSED: - deb_info("key pressed\n"); - d->last_event = event; - case REMOTE_KEY_REPEAT: - deb_info("key repeated\n"); - input_event(d->rc_input_dev, EV_KEY, event, 1); - input_sync(d->rc_input_dev); - input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); - input_sync(d->rc_input_dev); - break; - default: - break; - } + ir_keydown(d->rc_input_dev, keycode, toggle); resubmit: /* Clean the buffer before we requeue */ @@ -631,21 +613,10 @@ resubmit: int dib0700_rc_setup(struct dvb_usb_device *d) { struct dib0700_state *st = d->priv; - u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0}; struct urb *purb; int ret; - int i; - - if (d->props.rc_key_map == NULL) - return 0; - - /* Set the IR mode */ - i = dib0700_ctrl_wr(d, rc_setup, 3); - if (i<0) { - err("ir protocol setup failed"); - return -1; - } + /* Poll-based. Don't initialize bulk mode */ if (st->fw_version < 0x10200) return 0; @@ -653,14 +624,14 @@ int dib0700_rc_setup(struct dvb_usb_device *d) purb = usb_alloc_urb(0, GFP_KERNEL); if (purb == NULL) { err("rc usb alloc urb failed\n"); - return -1; + return -ENOMEM; } purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL); if (purb->transfer_buffer == NULL) { err("rc kzalloc failed\n"); usb_free_urb(purb); - return -1; + return -ENOMEM; } purb->status = -EINPROGRESS; @@ -669,12 +640,10 @@ int dib0700_rc_setup(struct dvb_usb_device *d) dib0700_rc_urb_completion, d); ret = usb_submit_urb(purb, GFP_ATOMIC); - if (ret != 0) { + if (ret) err("rc submit urb failed\n"); - return -1; - } - return 0; + return ret; } static int dib0700_probe(struct usb_interface *intf, @@ -698,6 +667,15 @@ static int dib0700_probe(struct usb_interface *intf, st->fw_version = fw_version; st->nb_packet_buffer_size = (u32)nb_packet_buffer_size; + /* Disable polling mode on newer firmwares */ + if (st->fw_version >= 0x10200) + dev->props.rc.core.bulk_mode = true; + else + dev->props.rc.core.bulk_mode = false; + + /* Need a higher delay, to avoid wrong repeat */ + dev->rc_input_dev->rep[REP_DELAY] = 500; + dib0700_rc_setup(dev); return 0; diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 800800a9649e..f634d2e784b2 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -473,16 +473,19 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; /* Number of keypresses to ignore before start repeating */ #define RC_REPEAT_DELAY 6 -static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +/* + * This function is used only when firmware is < 1.20 version. Newer + * firmwares use bulk mode, with functions implemented at dib0700_core, + * at dib0700_rc_urb_completion() + */ +static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) { u8 key[4]; + u32 keycode; + u8 toggle; int i; - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; struct dib0700_state *st = d->priv; - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - if (st->fw_version >= 0x10200) { /* For 1.20 firmware , We need to keep the RC polling callback so we can reuse the input device setup in @@ -491,348 +494,45 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) return 0; } - i=dib0700_ctrl_rd(d,rc_request,2,key,4); - if (i<=0) { + i = dib0700_ctrl_rd(d, rc_request, 2, key, 4); + if (i <= 0) { err("RC Query Failed"); return -1; } /* losing half of KEY_0 events from Philipps rc5 remotes.. */ - if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0; + if (key[0] == 0 && key[1] == 0 && key[2] == 0 && key[3] == 0) + return 0; /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */ dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */ - switch (dvb_usb_dib0700_ir_proto) { - case 0: { + d->last_event = 0; + switch (d->props.rc.core.protocol) { + case IR_TYPE_NEC: /* NEC protocol sends repeat code as 0 0 0 FF */ if ((key[3-2] == 0x00) && (key[3-3] == 0x00) && - (key[3] == 0xFF)) { - st->rc_counter++; - if (st->rc_counter > RC_REPEAT_DELAY) { - *event = d->last_event; - *state = REMOTE_KEY_PRESSED; - st->rc_counter = RC_REPEAT_DELAY; - } - return 0; - } - for (i=0;i<d->props.rc_key_map_size; i++) { - if (rc5_custom(&keymap[i]) == key[3-2] && - rc5_data(&keymap[i]) == key[3-3]) { - st->rc_counter = 0; - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - d->last_event = keymap[i].event; - return 0; - } + (key[3] == 0xff)) + keycode = d->last_event; + else { + keycode = key[3-2] << 8 | key[3-3]; + d->last_event = keycode; } + + ir_keydown(d->rc_input_dev, keycode, 0); break; - } - default: { + default: /* RC-5 protocol changes toggle bit on new keypress */ - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (rc5_custom(&keymap[i]) == key[3-2] && - rc5_data(&keymap[i]) == key[3-3]) { - if (d->last_event == keymap[i].event && - key[3-1] == st->rc_toggle) { - st->rc_counter++; - /* prevents unwanted double hits */ - if (st->rc_counter > RC_REPEAT_DELAY) { - *event = d->last_event; - *state = REMOTE_KEY_PRESSED; - st->rc_counter = RC_REPEAT_DELAY; - } - - return 0; - } - st->rc_counter = 0; - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - st->rc_toggle = key[3-1]; - d->last_event = keymap[i].event; - return 0; - } - } + keycode = key[3-2] << 8 | key[3-3]; + toggle = key[3-1]; + ir_keydown(d->rc_input_dev, keycode, toggle); + break; } - } - err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]); - d->last_event = 0; return 0; } -static struct dvb_usb_rc_key ir_codes_dib0700_table[] = { - /* Key codes for the tiny Pinnacle remote*/ - { 0x0700, KEY_MUTE }, - { 0x0701, KEY_MENU }, /* Pinnacle logo */ - { 0x0739, KEY_POWER }, - { 0x0703, KEY_VOLUMEUP }, - { 0x0709, KEY_VOLUMEDOWN }, - { 0x0706, KEY_CHANNELUP }, - { 0x070c, KEY_CHANNELDOWN }, - { 0x070f, KEY_1 }, - { 0x0715, KEY_2 }, - { 0x0710, KEY_3 }, - { 0x0718, KEY_4 }, - { 0x071b, KEY_5 }, - { 0x071e, KEY_6 }, - { 0x0711, KEY_7 }, - { 0x0721, KEY_8 }, - { 0x0712, KEY_9 }, - { 0x0727, KEY_0 }, - { 0x0724, KEY_SCREEN }, /* 'Square' key */ - { 0x072a, KEY_TEXT }, /* 'T' key */ - { 0x072d, KEY_REWIND }, - { 0x0730, KEY_PLAY }, - { 0x0733, KEY_FASTFORWARD }, - { 0x0736, KEY_RECORD }, - { 0x073c, KEY_STOP }, - { 0x073f, KEY_CANCEL }, /* '?' key */ - /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */ - { 0xeb01, KEY_POWER }, - { 0xeb02, KEY_1 }, - { 0xeb03, KEY_2 }, - { 0xeb04, KEY_3 }, - { 0xeb05, KEY_4 }, - { 0xeb06, KEY_5 }, - { 0xeb07, KEY_6 }, - { 0xeb08, KEY_7 }, - { 0xeb09, KEY_8 }, - { 0xeb0a, KEY_9 }, - { 0xeb0b, KEY_VIDEO }, - { 0xeb0c, KEY_0 }, - { 0xeb0d, KEY_REFRESH }, - { 0xeb0f, KEY_EPG }, - { 0xeb10, KEY_UP }, - { 0xeb11, KEY_LEFT }, - { 0xeb12, KEY_OK }, - { 0xeb13, KEY_RIGHT }, - { 0xeb14, KEY_DOWN }, - { 0xeb16, KEY_INFO }, - { 0xeb17, KEY_RED }, - { 0xeb18, KEY_GREEN }, - { 0xeb19, KEY_YELLOW }, - { 0xeb1a, KEY_BLUE }, - { 0xeb1b, KEY_CHANNELUP }, - { 0xeb1c, KEY_VOLUMEUP }, - { 0xeb1d, KEY_MUTE }, - { 0xeb1e, KEY_VOLUMEDOWN }, - { 0xeb1f, KEY_CHANNELDOWN }, - { 0xeb40, KEY_PAUSE }, - { 0xeb41, KEY_HOME }, - { 0xeb42, KEY_MENU }, /* DVD Menu */ - { 0xeb43, KEY_SUBTITLE }, - { 0xeb44, KEY_TEXT }, /* Teletext */ - { 0xeb45, KEY_DELETE }, - { 0xeb46, KEY_TV }, - { 0xeb47, KEY_DVD }, - { 0xeb48, KEY_STOP }, - { 0xeb49, KEY_VIDEO }, - { 0xeb4a, KEY_AUDIO }, /* Music */ - { 0xeb4b, KEY_SCREEN }, /* Pic */ - { 0xeb4c, KEY_PLAY }, - { 0xeb4d, KEY_BACK }, - { 0xeb4e, KEY_REWIND }, - { 0xeb4f, KEY_FASTFORWARD }, - { 0xeb54, KEY_PREVIOUS }, - { 0xeb58, KEY_RECORD }, - { 0xeb5c, KEY_NEXT }, - - /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */ - { 0x1e00, KEY_0 }, - { 0x1e01, KEY_1 }, - { 0x1e02, KEY_2 }, - { 0x1e03, KEY_3 }, - { 0x1e04, KEY_4 }, - { 0x1e05, KEY_5 }, - { 0x1e06, KEY_6 }, - { 0x1e07, KEY_7 }, - { 0x1e08, KEY_8 }, - { 0x1e09, KEY_9 }, - { 0x1e0a, KEY_KPASTERISK }, - { 0x1e0b, KEY_RED }, - { 0x1e0c, KEY_RADIO }, - { 0x1e0d, KEY_MENU }, - { 0x1e0e, KEY_GRAVE }, /* # */ - { 0x1e0f, KEY_MUTE }, - { 0x1e10, KEY_VOLUMEUP }, - { 0x1e11, KEY_VOLUMEDOWN }, - { 0x1e12, KEY_CHANNEL }, - { 0x1e14, KEY_UP }, - { 0x1e15, KEY_DOWN }, - { 0x1e16, KEY_LEFT }, - { 0x1e17, KEY_RIGHT }, - { 0x1e18, KEY_VIDEO }, - { 0x1e19, KEY_AUDIO }, - { 0x1e1a, KEY_MEDIA }, - { 0x1e1b, KEY_EPG }, - { 0x1e1c, KEY_TV }, - { 0x1e1e, KEY_NEXT }, - { 0x1e1f, KEY_BACK }, - { 0x1e20, KEY_CHANNELUP }, - { 0x1e21, KEY_CHANNELDOWN }, - { 0x1e24, KEY_LAST }, /* Skip backwards */ - { 0x1e25, KEY_OK }, - { 0x1e29, KEY_BLUE}, - { 0x1e2e, KEY_GREEN }, - { 0x1e30, KEY_PAUSE }, - { 0x1e32, KEY_REWIND }, - { 0x1e34, KEY_FASTFORWARD }, - { 0x1e35, KEY_PLAY }, - { 0x1e36, KEY_STOP }, - { 0x1e37, KEY_RECORD }, - { 0x1e38, KEY_YELLOW }, - { 0x1e3b, KEY_GOTO }, - { 0x1e3d, KEY_POWER }, - - /* Key codes for the Leadtek Winfast DTV Dongle */ - { 0x0042, KEY_POWER }, - { 0x077c, KEY_TUNER }, - { 0x0f4e, KEY_PRINT }, /* PREVIEW */ - { 0x0840, KEY_SCREEN }, /* full screen toggle*/ - { 0x0f71, KEY_DOT }, /* frequency */ - { 0x0743, KEY_0 }, - { 0x0c41, KEY_1 }, - { 0x0443, KEY_2 }, - { 0x0b7f, KEY_3 }, - { 0x0e41, KEY_4 }, - { 0x0643, KEY_5 }, - { 0x097f, KEY_6 }, - { 0x0d7e, KEY_7 }, - { 0x057c, KEY_8 }, - { 0x0a40, KEY_9 }, - { 0x0e4e, KEY_CLEAR }, - { 0x047c, KEY_CHANNEL }, /* show channel number */ - { 0x0f41, KEY_LAST }, /* recall */ - { 0x0342, KEY_MUTE }, - { 0x064c, KEY_RESERVED }, /* PIP button*/ - { 0x0172, KEY_SHUFFLE }, /* SNAPSHOT */ - { 0x0c4e, KEY_PLAYPAUSE }, /* TIMESHIFT */ - { 0x0b70, KEY_RECORD }, - { 0x037d, KEY_VOLUMEUP }, - { 0x017d, KEY_VOLUMEDOWN }, - { 0x0242, KEY_CHANNELUP }, - { 0x007d, KEY_CHANNELDOWN }, - - /* Key codes for Nova-TD "credit card" remote control. */ - { 0x1d00, KEY_0 }, - { 0x1d01, KEY_1 }, - { 0x1d02, KEY_2 }, - { 0x1d03, KEY_3 }, - { 0x1d04, KEY_4 }, - { 0x1d05, KEY_5 }, - { 0x1d06, KEY_6 }, - { 0x1d07, KEY_7 }, - { 0x1d08, KEY_8 }, - { 0x1d09, KEY_9 }, - { 0x1d0a, KEY_TEXT }, - { 0x1d0d, KEY_MENU }, - { 0x1d0f, KEY_MUTE }, - { 0x1d10, KEY_VOLUMEUP }, - { 0x1d11, KEY_VOLUMEDOWN }, - { 0x1d12, KEY_CHANNEL }, - { 0x1d14, KEY_UP }, - { 0x1d15, KEY_DOWN }, - { 0x1d16, KEY_LEFT }, - { 0x1d17, KEY_RIGHT }, - { 0x1d1c, KEY_TV }, - { 0x1d1e, KEY_NEXT }, - { 0x1d1f, KEY_BACK }, - { 0x1d20, KEY_CHANNELUP }, - { 0x1d21, KEY_CHANNELDOWN }, - { 0x1d24, KEY_LAST }, - { 0x1d25, KEY_OK }, - { 0x1d30, KEY_PAUSE }, - { 0x1d32, KEY_REWIND }, - { 0x1d34, KEY_FASTFORWARD }, - { 0x1d35, KEY_PLAY }, - { 0x1d36, KEY_STOP }, - { 0x1d37, KEY_RECORD }, - { 0x1d3b, KEY_GOTO }, - { 0x1d3d, KEY_POWER }, - - /* Key codes for the Pixelview SBTVD remote (proto NEC) */ - { 0x8613, KEY_MUTE }, - { 0x8612, KEY_POWER }, - { 0x8601, KEY_1 }, - { 0x8602, KEY_2 }, - { 0x8603, KEY_3 }, - { 0x8604, KEY_4 }, - { 0x8605, KEY_5 }, - { 0x8606, KEY_6 }, - { 0x8607, KEY_7 }, - { 0x8608, KEY_8 }, - { 0x8609, KEY_9 }, - { 0x8600, KEY_0 }, - { 0x860d, KEY_CHANNELUP }, - { 0x8619, KEY_CHANNELDOWN }, - { 0x8610, KEY_VOLUMEUP }, - { 0x860c, KEY_VOLUMEDOWN }, - - { 0x860a, KEY_CAMERA }, - { 0x860b, KEY_ZOOM }, - { 0x861b, KEY_BACKSPACE }, - { 0x8615, KEY_ENTER }, - - { 0x861d, KEY_UP }, - { 0x861e, KEY_DOWN }, - { 0x860e, KEY_LEFT }, - { 0x860f, KEY_RIGHT }, - - { 0x8618, KEY_RECORD }, - { 0x861a, KEY_STOP }, - - /* Key codes for the EvolutePC TVWay+ remote (proto NEC) */ - { 0x7a00, KEY_MENU }, - { 0x7a01, KEY_RECORD }, - { 0x7a02, KEY_PLAY }, - { 0x7a03, KEY_STOP }, - { 0x7a10, KEY_CHANNELUP }, - { 0x7a11, KEY_CHANNELDOWN }, - { 0x7a12, KEY_VOLUMEUP }, - { 0x7a13, KEY_VOLUMEDOWN }, - { 0x7a40, KEY_POWER }, - { 0x7a41, KEY_MUTE }, - - /* Key codes for the Elgato EyeTV Diversity silver remote, - set dvb_usb_dib0700_ir_proto=0 */ - { 0x4501, KEY_POWER }, - { 0x4502, KEY_MUTE }, - { 0x4503, KEY_1 }, - { 0x4504, KEY_2 }, - { 0x4505, KEY_3 }, - { 0x4506, KEY_4 }, - { 0x4507, KEY_5 }, - { 0x4508, KEY_6 }, - { 0x4509, KEY_7 }, - { 0x450a, KEY_8 }, - { 0x450b, KEY_9 }, - { 0x450c, KEY_LAST }, - { 0x450d, KEY_0 }, - { 0x450e, KEY_ENTER }, - { 0x450f, KEY_RED }, - { 0x4510, KEY_CHANNELUP }, - { 0x4511, KEY_GREEN }, - { 0x4512, KEY_VOLUMEDOWN }, - { 0x4513, KEY_OK }, - { 0x4514, KEY_VOLUMEUP }, - { 0x4515, KEY_YELLOW }, - { 0x4516, KEY_CHANNELDOWN }, - { 0x4517, KEY_BLUE }, - { 0x4518, KEY_LEFT }, /* Skip backwards */ - { 0x4519, KEY_PLAYPAUSE }, - { 0x451a, KEY_RIGHT }, /* Skip forward */ - { 0x451b, KEY_REWIND }, - { 0x451c, KEY_L }, /* Live */ - { 0x451d, KEY_FASTFORWARD }, - { 0x451e, KEY_STOP }, /* 'Reveal' for Teletext */ - { 0x451f, KEY_MENU }, /* KEY_TEXT for Teletext */ - { 0x4540, KEY_RECORD }, /* Font 'Size' for Teletext */ - { 0x4541, KEY_SCREEN }, /* Full screen toggle, 'Hold' for Teletext */ - { 0x4542, KEY_SELECT }, /* Select video input, 'Select' for Teletext */ -}; - /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = { BAND_UHF | BAND_VHF, @@ -2168,10 +1868,17 @@ struct dvb_usb_device_properties dib0700_devices[] = { } }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 2, @@ -2197,10 +1904,17 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 2, @@ -2251,11 +1965,17 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query - + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, @@ -2288,10 +2008,18 @@ struct dvb_usb_device_properties dib0700_devices[] = { } }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, @@ -2358,11 +2086,18 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query - + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, @@ -2397,11 +2132,18 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query - + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 2, @@ -2431,7 +2173,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { } }, - .num_device_descs = 7, + .num_device_descs = 6, .devices = { { "DiBcom STK7070PD reference design", { &dib0700_usb_id_table[17], NULL }, @@ -2458,15 +2200,69 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[44], NULL }, { NULL }, }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + + .num_adapters = 2, + .adapter = { + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .frontend_attach = stk7070pd_frontend_attach0, + .tuner_attach = dib7070p_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + .size_of_priv = sizeof(struct dib0700_adapter_state), + }, { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .frontend_attach = stk7070pd_frontend_attach1, + .tuner_attach = dib7070p_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x03), + + .size_of_priv = sizeof(struct dib0700_adapter_state), + } + }, + + .num_device_descs = 1, + .devices = { { "Elgato EyeTV Diversity", { &dib0700_usb_id_table[68], NULL }, { NULL }, }, }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_NEC_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, @@ -2525,10 +2321,19 @@ struct dvb_usb_device_properties dib0700_devices[] = { { NULL }, }, }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, .adapter = { @@ -2554,10 +2359,19 @@ struct dvb_usb_device_properties dib0700_devices[] = { { NULL }, }, }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, .adapter = { @@ -2615,10 +2429,19 @@ struct dvb_usb_device_properties dib0700_devices[] = { { NULL }, }, }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, .adapter = { @@ -2653,11 +2476,18 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query - + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_NEC_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 2, .adapter = { @@ -2697,10 +2527,18 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, .adapter = { @@ -2728,10 +2566,18 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dib0700_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table), - .rc_query = dib0700_rc_query + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .rc_props = { + .allowed_protos = IR_TYPE_RC5 | + IR_TYPE_RC6 | + IR_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, }, }; diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index bc08bc0b723c..ba991aa21aff 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -327,7 +327,7 @@ EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); /* * common remote control stuff */ -struct dvb_usb_rc_key ir_codes_dibusb_table[] = { +struct ir_scancode ir_codes_dibusb_table[] = { /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */ { 0x0016, KEY_POWER }, { 0x0010, KEY_MUTE }, diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index eb2e6f050fbe..8e3c0d2cce16 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -211,10 +211,12 @@ static struct dvb_usb_device_properties dibusb1_1_properties = { .power_ctrl = dibusb_power_ctrl, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dibusb_table, - .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ - .rc_query = dibusb_rc_query, + .rc.legacy = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = ir_codes_dibusb_table, + .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ + .rc_query = dibusb_rc_query, + }, .i2c_algo = &dibusb_i2c_algo, @@ -295,10 +297,12 @@ static struct dvb_usb_device_properties dibusb1_1_an2235_properties = { }, .power_ctrl = dibusb_power_ctrl, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dibusb_table, - .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ - .rc_query = dibusb_rc_query, + .rc.legacy = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = ir_codes_dibusb_table, + .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ + .rc_query = dibusb_rc_query, + }, .i2c_algo = &dibusb_i2c_algo, @@ -359,10 +363,12 @@ static struct dvb_usb_device_properties dibusb2_0b_properties = { }, .power_ctrl = dibusb2_0_power_ctrl, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dibusb_table, - .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ - .rc_query = dibusb_rc_query, + .rc.legacy = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = ir_codes_dibusb_table, + .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ + .rc_query = dibusb_rc_query, + }, .i2c_algo = &dibusb_i2c_algo, @@ -416,10 +422,12 @@ static struct dvb_usb_device_properties artec_t1_usb2_properties = { }, .power_ctrl = dibusb2_0_power_ctrl, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dibusb_table, - .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ - .rc_query = dibusb_rc_query, + .rc.legacy = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = ir_codes_dibusb_table, + .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ + .rc_query = dibusb_rc_query, + }, .i2c_algo = &dibusb_i2c_algo, diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c index 588308eb6638..1cbc41cb4e8f 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mc.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c @@ -81,10 +81,12 @@ static struct dvb_usb_device_properties dibusb_mc_properties = { }, .power_ctrl = dibusb2_0_power_ctrl, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = ir_codes_dibusb_table, - .rc_key_map_size = 111, /* FIXME */ - .rc_query = dibusb_rc_query, + .rc.legacy = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = ir_codes_dibusb_table, + .rc_key_map_size = 111, /* FIXME */ + .rc_query = dibusb_rc_query, + }, .i2c_algo = &dibusb_i2c_algo, diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h index 3d50ac59088f..61a6bf389472 100644 --- a/drivers/media/dvb/dvb-usb/dibusb.h +++ b/drivers/media/dvb/dvb-usb/dibusb.h @@ -124,7 +124,7 @@ extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int); #define DEFAULT_RC_INTERVAL 150 //#define DEFAULT_RC_INTERVAL 100000 -extern struct dvb_usb_rc_key ir_codes_dibusb_table[]; +extern struct ir_scancode ir_codes_dibusb_table[]; extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *); extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *); diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index e826077094fa..13d006bb19db 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -161,7 +161,7 @@ static int digitv_tuner_attach(struct dvb_usb_adapter *adap) return 0; } -static struct dvb_usb_rc_key ir_codes_digitv_table[] = { +static struct ir_scancode ir_codes_digitv_table[] = { { 0x5f55, KEY_0 }, { 0x6f55, KEY_1 }, { 0x9f55, KEY_2 }, @@ -237,10 +237,10 @@ static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state) /* if something is inside the buffer, simulate key press */ if (key[1] != 0) { - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (rc5_custom(&d->props.rc_key_map[i]) == key[1] && - rc5_data(&d->props.rc_key_map[i]) == key[2]) { - *event = d->props.rc_key_map[i].event; + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { + if (rc5_custom(&d->props.rc.legacy.rc_key_map[i]) == key[1] && + rc5_data(&d->props.rc.legacy.rc_key_map[i]) == key[2]) { + *event = d->props.rc.legacy.rc_key_map[i].keycode; *state = REMOTE_KEY_PRESSED; return 0; } @@ -310,10 +310,12 @@ static struct dvb_usb_device_properties digitv_properties = { }, .identify_state = digitv_identify_state, - .rc_interval = 1000, - .rc_key_map = ir_codes_digitv_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_digitv_table), - .rc_query = digitv_rc_query, + .rc.legacy = { + .rc_interval = 1000, + .rc_key_map = ir_codes_digitv_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_digitv_table), + .rc_query = digitv_rc_query, + }, .i2c_algo = &digitv_i2c_algo, diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index f57e59044d4d..ca495e07f35c 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c @@ -57,7 +57,7 @@ static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, /* remote control */ /* key list for the tiny remote control (Yakumo, don't know about the others) */ -static struct dvb_usb_rc_key ir_codes_dtt200u_table[] = { +static struct ir_scancode ir_codes_dtt200u_table[] = { { 0x8001, KEY_MUTE }, { 0x8002, KEY_CHANNELDOWN }, { 0x8003, KEY_VOLUMEDOWN }, @@ -161,10 +161,12 @@ static struct dvb_usb_device_properties dtt200u_properties = { }, .power_ctrl = dtt200u_power_ctrl, - .rc_interval = 300, - .rc_key_map = ir_codes_dtt200u_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table), - .rc_query = dtt200u_rc_query, + .rc.legacy = { + .rc_interval = 300, + .rc_key_map = ir_codes_dtt200u_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table), + .rc_query = dtt200u_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x01, @@ -206,10 +208,12 @@ static struct dvb_usb_device_properties wt220u_properties = { }, .power_ctrl = dtt200u_power_ctrl, - .rc_interval = 300, - .rc_key_map = ir_codes_dtt200u_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table), - .rc_query = dtt200u_rc_query, + .rc.legacy = { + .rc_interval = 300, + .rc_key_map = ir_codes_dtt200u_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table), + .rc_query = dtt200u_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x01, @@ -251,10 +255,12 @@ static struct dvb_usb_device_properties wt220u_fc_properties = { }, .power_ctrl = dtt200u_power_ctrl, - .rc_interval = 300, - .rc_key_map = ir_codes_dtt200u_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table), - .rc_query = dtt200u_rc_query, + .rc.legacy = { + .rc_interval = 300, + .rc_key_map = ir_codes_dtt200u_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table), + .rc_query = dtt200u_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x01, @@ -296,10 +302,12 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = { }, .power_ctrl = dtt200u_power_ctrl, - .rc_interval = 300, - .rc_key_map = ir_codes_dtt200u_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table), - .rc_query = dtt200u_rc_query, + .rc.legacy = { + .rc_interval = 300, + .rc_key_map = ir_codes_dtt200u_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table), + .rc_query = dtt200u_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x01, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index b4afe6f8ed19..1a774d58d664 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -197,6 +197,7 @@ #define USB_PID_AVERMEDIA_A310 0xa310 #define USB_PID_AVERMEDIA_A850 0x850a #define USB_PID_AVERMEDIA_A805 0xa805 +#define USB_PID_AVERMEDIA_A815M 0x815a #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 #define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index 5d91f70d2d2d..2e3ea0fa28e0 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -15,7 +15,7 @@ /* debug */ int dvb_usb_debug; -module_param_named(debug,dvb_usb_debug, int, 0644); +module_param_named(debug, dvb_usb_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256 (or-able))." DVB_USB_DEBUG_STATUS); int dvb_usb_disable_rc_polling; @@ -29,7 +29,7 @@ MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) { struct dvb_usb_adapter *adap; - int ret,n; + int ret, n; for (n = 0; n < d->props.num_adapters; n++) { adap = &d->adapter[n]; @@ -38,7 +38,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) memcpy(&adap->props, &d->props.adapter[n], sizeof(struct dvb_usb_adapter_properties)); -/* speed - when running at FULL speed we need a HW PID filter */ + /* speed - when running at FULL speed we need a HW PID filter */ if (d->udev->speed == USB_SPEED_FULL && !(adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER)) { err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)"); return -ENODEV; @@ -46,7 +46,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) if ((d->udev->speed == USB_SPEED_FULL && adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER) || (adap->props.caps & DVB_USB_ADAP_NEED_PID_FILTERING)) { - info("will use the device's hardware PID filter (table count: %d).",adap->props.pid_filter_count); + info("will use the device's hardware PID filter (table count: %d).", adap->props.pid_filter_count); adap->pid_filtering = 1; adap->max_feed_count = adap->props.pid_filter_count; } else { @@ -64,9 +64,9 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) } if (adap->props.size_of_priv > 0) { - adap->priv = kzalloc(adap->props.size_of_priv,GFP_KERNEL); + adap->priv = kzalloc(adap->props.size_of_priv, GFP_KERNEL); if (adap->priv == NULL) { - err("no memory for priv for adapter %d.",n); + err("no memory for priv for adapter %d.", n); return -ENOMEM; } } @@ -86,8 +86,8 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) * sometimes a timeout occures, this helps */ if (d->props.generic_bulk_ctrl_endpoint != 0) { - usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint)); - usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); } return 0; @@ -96,6 +96,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) static int dvb_usb_adapter_exit(struct dvb_usb_device *d) { int n; + for (n = 0; n < d->num_adapters_initialized; n++) { dvb_usb_adapter_frontend_exit(&d->adapter[n]); dvb_usb_adapter_dvb_exit(&d->adapter[n]); @@ -111,11 +112,11 @@ static int dvb_usb_adapter_exit(struct dvb_usb_device *d) /* general initialization functions */ static int dvb_usb_exit(struct dvb_usb_device *d) { - deb_info("state before exiting everything: %x\n",d->state); + deb_info("state before exiting everything: %x\n", d->state); dvb_usb_remote_exit(d); dvb_usb_adapter_exit(d); dvb_usb_i2c_exit(d); - deb_info("state should be zero now: %x\n",d->state); + deb_info("state should be zero now: %x\n", d->state); d->state = DVB_USB_STATE_INIT; kfree(d->priv); kfree(d); @@ -132,14 +133,14 @@ static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums) d->state = DVB_USB_STATE_INIT; if (d->props.size_of_priv > 0) { - d->priv = kzalloc(d->props.size_of_priv,GFP_KERNEL); + d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL); if (d->priv == NULL) { err("no memory for priv in 'struct dvb_usb_device'"); return -ENOMEM; } } -/* check the capabilities and set appropriate variables */ + /* check the capabilities and set appropriate variables */ dvb_usb_device_power_ctrl(d, 1); if ((ret = dvb_usb_i2c_init(d)) || @@ -157,16 +158,17 @@ static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums) } /* determine the name and the state of the just found USB device */ -static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_device_properties *props, int *cold) +static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device *udev, struct dvb_usb_device_properties *props, int *cold) { - int i,j; + int i, j; struct dvb_usb_device_description *desc = NULL; + *cold = -1; for (i = 0; i < props->num_device_descs; i++) { for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) { - deb_info("check for cold %x %x\n",props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct); + deb_info("check for cold %x %x\n", props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct); if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) && props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) { *cold = 1; @@ -179,7 +181,7 @@ static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device break; for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) { - deb_info("check for warm %x %x\n",props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct); + deb_info("check for warm %x %x\n", props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct); if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) && props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) { *cold = 0; @@ -190,7 +192,7 @@ static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device } if (desc != NULL && props->identify_state != NULL) - props->identify_state(udev,props,&desc,cold); + props->identify_state(udev, props, &desc, cold); return desc; } @@ -202,7 +204,7 @@ int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff) else d->powered--; - if (d->powered == 0 || (onoff && d->powered == 1)) { // when switching from 1 to 0 or from 0 to 1 + if (d->powered == 0 || (onoff && d->powered == 1)) { /* when switching from 1 to 0 or from 0 to 1 */ deb_info("power control: %d\n", onoff); if (d->props.power_ctrl) return d->props.power_ctrl(d, onoff); @@ -222,32 +224,32 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_device *d = NULL; struct dvb_usb_device_description *desc = NULL; - int ret = -ENOMEM,cold=0; + int ret = -ENOMEM, cold = 0; if (du != NULL) *du = NULL; - if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) { + if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) { deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); return -ENODEV; } if (cold) { - info("found a '%s' in cold state, will try to load a firmware",desc->name); - ret = dvb_usb_download_firmware(udev,props); + info("found a '%s' in cold state, will try to load a firmware", desc->name); + ret = dvb_usb_download_firmware(udev, props); if (!props->no_reconnect || ret != 0) return ret; } - info("found a '%s' in warm state.",desc->name); - d = kzalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); + info("found a '%s' in warm state.", desc->name); + d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); if (d == NULL) { err("no memory for 'struct dvb_usb_device'"); return -ENOMEM; } d->udev = udev; - memcpy(&d->props,props,sizeof(struct dvb_usb_device_properties)); + memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); d->desc = desc; d->owner = owner; @@ -259,9 +261,9 @@ int dvb_usb_device_init(struct usb_interface *intf, ret = dvb_usb_init(d, adapter_nums); if (ret == 0) - info("%s successfully initialized and connected.",desc->name); + info("%s successfully initialized and connected.", desc->name); else - info("%s error while loading driver (%d)",desc->name,ret); + info("%s error while loading driver (%d)", desc->name, ret); return ret; } EXPORT_SYMBOL(dvb_usb_device_init); @@ -271,12 +273,12 @@ void dvb_usb_device_exit(struct usb_interface *intf) struct dvb_usb_device *d = usb_get_intfdata(intf); const char *name = "generic DVB-USB module"; - usb_set_intfdata(intf,NULL); + usb_set_intfdata(intf, NULL); if (d != NULL && d->desc != NULL) { name = d->desc->name; dvb_usb_exit(d); } - info("%s successfully deinitialized and disconnected.",name); + info("%s successfully deinitialized and disconnected.", name); } EXPORT_SYMBOL(dvb_usb_device_exit); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 852fe89539cf..b579fed3ab3f 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -8,29 +8,29 @@ #include "dvb-usb-common.h" #include <linux/usb/input.h> -static int dvb_usb_getkeycode(struct input_dev *dev, +static int legacy_dvb_usb_getkeycode(struct input_dev *dev, unsigned int scancode, unsigned int *keycode) { struct dvb_usb_device *d = input_get_drvdata(dev); - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; int i; /* See if we can match the raw key code. */ - for (i = 0; i < d->props.rc_key_map_size; i++) - if (keymap[i].scan == scancode) { - *keycode = keymap[i].event; + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) + if (keymap[i].scancode == scancode) { + *keycode = keymap[i].keycode; return 0; } /* * If is there extra space, returns KEY_RESERVED, - * otherwise, input core won't let dvb_usb_setkeycode + * otherwise, input core won't let legacy_dvb_usb_setkeycode * to work */ - for (i = 0; i < d->props.rc_key_map_size; i++) - if (keymap[i].event == KEY_RESERVED || - keymap[i].event == KEY_UNKNOWN) { + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) + if (keymap[i].keycode == KEY_RESERVED || + keymap[i].keycode == KEY_UNKNOWN) { *keycode = KEY_RESERVED; return 0; } @@ -38,27 +38,27 @@ static int dvb_usb_getkeycode(struct input_dev *dev, return -EINVAL; } -static int dvb_usb_setkeycode(struct input_dev *dev, +static int legacy_dvb_usb_setkeycode(struct input_dev *dev, unsigned int scancode, unsigned int keycode) { struct dvb_usb_device *d = input_get_drvdata(dev); - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; int i; /* Search if it is replacing an existing keycode */ - for (i = 0; i < d->props.rc_key_map_size; i++) - if (keymap[i].scan == scancode) { - keymap[i].event = keycode; + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) + if (keymap[i].scancode == scancode) { + keymap[i].keycode = keycode; return 0; } /* Search if is there a clean entry. If so, use it */ - for (i = 0; i < d->props.rc_key_map_size; i++) - if (keymap[i].event == KEY_RESERVED || - keymap[i].event == KEY_UNKNOWN) { - keymap[i].scan = scancode; - keymap[i].event = keycode; + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) + if (keymap[i].keycode == KEY_RESERVED || + keymap[i].keycode == KEY_UNKNOWN) { + keymap[i].scancode = scancode; + keymap[i].keycode = keycode; return 0; } @@ -78,7 +78,7 @@ static int dvb_usb_setkeycode(struct input_dev *dev, * * TODO: Fix the repeat rate of the input device. */ -static void dvb_usb_read_remote_control(struct work_struct *work) +static void legacy_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); @@ -92,7 +92,7 @@ static void dvb_usb_read_remote_control(struct work_struct *work) if (dvb_usb_disable_rc_polling) return; - if (d->props.rc_query(d,&event,&state)) { + if (d->props.rc.legacy.rc_query(d,&event,&state)) { err("error while querying for an remote control event."); goto schedule; } @@ -151,18 +151,117 @@ static void dvb_usb_read_remote_control(struct work_struct *work) */ schedule: - schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); + schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval)); +} + +static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d, + struct input_dev *input_dev) +{ + int i, err, rc_interval; + + input_dev->getkeycode = legacy_dvb_usb_getkeycode; + input_dev->setkeycode = legacy_dvb_usb_setkeycode; + + /* set the bits for the keys */ + deb_rc("key map size: %d\n", d->props.rc.legacy.rc_key_map_size); + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { + deb_rc("setting bit for event %d item %d\n", + d->props.rc.legacy.rc_key_map[i].keycode, i); + set_bit(d->props.rc.legacy.rc_key_map[i].keycode, input_dev->keybit); + } + + /* setting these two values to non-zero, we have to manage key repeats */ + input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval; + input_dev->rep[REP_DELAY] = d->props.rc.legacy.rc_interval + 150; + + input_set_drvdata(input_dev, d); + + err = input_register_device(input_dev); + if (err) + input_free_device(input_dev); + + rc_interval = d->props.rc.legacy.rc_interval; + + INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control); + + info("schedule remote query interval to %d msecs.", rc_interval); + schedule_delayed_work(&d->rc_query_work, + msecs_to_jiffies(rc_interval)); + + d->state |= DVB_USB_STATE_REMOTE; + + return err; +} + +/* Remote-control poll function - called every dib->rc_query_interval ms to see + * whether the remote control has received anything. + * + * TODO: Fix the repeat rate of the input device. + */ +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; + + /* TODO: need a lock here. We can simply skip checking for the remote control + if we're busy. */ + + /* 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.core.bulk_mode) + return; + + err = d->props.rc.core.rc_query(d); + if (err) + err("error %d while querying for an remote control event.", err); + + schedule_delayed_work(&d->rc_query_work, + msecs_to_jiffies(d->props.rc.core.rc_interval)); +} + +static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d, + struct input_dev *input_dev) +{ + int err, rc_interval; + + d->props.rc.core.rc_props.priv = d; + err = ir_input_register(input_dev, + d->props.rc.core.rc_codes, + &d->props.rc.core.rc_props, + d->props.rc.core.module_name); + if (err < 0) + return err; + + if (!d->props.rc.core.rc_query || d->props.rc.core.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); + + rc_interval = d->props.rc.core.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) { struct input_dev *input_dev; - int i; int err; - if (d->props.rc_key_map == NULL || - d->props.rc_query == NULL || - dvb_usb_disable_rc_polling) + if (dvb_usb_disable_rc_polling) + return 0; + + if (d->props.rc.legacy.rc_key_map && d->props.rc.legacy.rc_query) + d->props.rc.mode = DVB_RC_LEGACY; + else if (d->props.rc.core.rc_codes) + d->props.rc.mode = DVB_RC_CORE; + else return 0; usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); @@ -177,39 +276,19 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) input_dev->phys = d->rc_phys; usb_to_input_id(d->udev, &input_dev->id); input_dev->dev.parent = &d->udev->dev; - input_dev->getkeycode = dvb_usb_getkeycode; - input_dev->setkeycode = dvb_usb_setkeycode; - - /* set the bits for the keys */ - deb_rc("key map size: %d\n", d->props.rc_key_map_size); - for (i = 0; i < d->props.rc_key_map_size; i++) { - deb_rc("setting bit for event %d item %d\n", - d->props.rc_key_map[i].event, i); - set_bit(d->props.rc_key_map[i].event, input_dev->keybit); - } /* Start the remote-control polling. */ - if (d->props.rc_interval < 40) - d->props.rc_interval = 100; /* default */ - - /* setting these two values to non-zero, we have to manage key repeats */ - input_dev->rep[REP_PERIOD] = d->props.rc_interval; - input_dev->rep[REP_DELAY] = d->props.rc_interval + 150; - - input_set_drvdata(input_dev, d); - - err = input_register_device(input_dev); - if (err) { - input_free_device(input_dev); - return err; - } + if (d->props.rc.legacy.rc_interval < 40) + d->props.rc.legacy.rc_interval = 100; /* default */ d->rc_input_dev = input_dev; - INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control); - - info("schedule remote query interval to %d msecs.", d->props.rc_interval); - schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); + if (d->props.rc.mode == DVB_RC_LEGACY) + err = legacy_dvb_usb_remote_init(d, input_dev); + else + err = rc_core_dvb_usb_remote_init(d, input_dev); + if (err) + return err; d->state |= DVB_USB_STATE_REMOTE; @@ -221,7 +300,10 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d) if (d->state & DVB_USB_STATE_REMOTE) { cancel_rearming_delayed_work(&d->rc_query_work); flush_scheduled_work(); - input_unregister_device(d->rc_input_dev); + if (d->props.rc.mode == DVB_RC_LEGACY) + input_unregister_device(d->rc_input_dev); + else + ir_input_unregister(d->rc_input_dev); } d->state &= ~DVB_USB_STATE_REMOTE; return 0; @@ -234,7 +316,7 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d, u8 keybuf[5], u32 *event, int *state) { int i; - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; *event = 0; *state = REMOTE_NO_KEY_PRESSED; switch (keybuf[0]) { @@ -247,10 +329,10 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d, break; } /* See if we can match the raw key code. */ - for (i = 0; i < d->props.rc_key_map_size; i++) + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) if (rc5_custom(&keymap[i]) == keybuf[1] && rc5_data(&keymap[i]) == keybuf[3]) { - *event = keymap[i].event; + *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; return 0; } diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index 4a9f676087bf..34f7b3ba8cc7 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -14,6 +14,7 @@ #include <linux/usb.h> #include <linux/firmware.h> #include <linux/mutex.h> +#include <media/ir-core.h> #include "dvb_frontend.h" #include "dvb_demux.h" @@ -74,30 +75,19 @@ struct dvb_usb_device_description { struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM]; }; -/** - * struct dvb_usb_rc_key - a remote control key and its input-event - * @custom: the vendor/custom part of the key - * @data: the actual key part - * @event: the input event assigned to key identified by custom and data - */ -struct dvb_usb_rc_key { - u16 scan; - u32 event; -}; - -static inline u8 rc5_custom(struct dvb_usb_rc_key *key) +static inline u8 rc5_custom(struct ir_scancode *key) { - return (key->scan >> 8) & 0xff; + return (key->scancode >> 8) & 0xff; } -static inline u8 rc5_data(struct dvb_usb_rc_key *key) +static inline u8 rc5_data(struct ir_scancode *key) { - return key->scan & 0xff; + return key->scancode & 0xff; } -static inline u8 rc5_scan(struct dvb_usb_rc_key *key) +static inline u8 rc5_scan(struct ir_scancode *key) { - return key->scan & 0xffff; + return key->scancode & 0xffff; } struct dvb_usb_device; @@ -168,6 +158,55 @@ struct dvb_usb_adapter_properties { }; /** + * struct dvb_rc_legacy - old properties of remote controller + * @rc_key_map: a hard-wired array of struct ir_scancode (NULL to disable + * remote control handling). + * @rc_key_map_size: number of items in @rc_key_map. + * @rc_query: called to query an event event. + * @rc_interval: time in ms between two queries. + */ +struct dvb_rc_legacy { +/* remote control properties */ +#define REMOTE_NO_KEY_PRESSED 0x00 +#define REMOTE_KEY_PRESSED 0x01 +#define REMOTE_KEY_REPEAT 0x02 + struct ir_scancode *rc_key_map; + int rc_key_map_size; + int (*rc_query) (struct dvb_usb_device *, u32 *, int *); + int rc_interval; +}; + +/** + * struct dvb_rc properties of remote controller, using rc-core + * @rc_codes: name of rc codes table + * @protocol: type of protocol(s) currently used by the driver + * @rc_query: called to query an event event. + * @rc_interval: time in ms between two queries. + * @rc_props: remote controller properties + * @bulk_mode: device supports bulk mode for RC (disable polling mode) + */ +struct dvb_rc { + char *rc_codes; + u64 protocol; + char *module_name; + int (*rc_query) (struct dvb_usb_device *d); + int rc_interval; + struct ir_dev_props rc_props; + bool bulk_mode; /* uses bulk mode */ +}; + +/** + * enum dvb_usb_mode - Specifies if it is using a legacy driver or a new one + * based on rc-core + * This is initialized/used only inside dvb-usb-remote.c. + * It shouldn't be set by the drivers. + */ +enum dvb_usb_mode { + DVB_RC_LEGACY, + DVB_RC_CORE, +}; + +/** * struct dvb_usb_device_properties - properties of a dvb-usb-device * @usb_ctrl: which USB device-side controller is in use. Needed for firmware * download. @@ -185,11 +224,7 @@ struct dvb_usb_adapter_properties { * @identify_state: called to determine the state (cold or warm), when it * is not distinguishable by the USB IDs. * - * @rc_key_map: a hard-wired array of struct dvb_usb_rc_key (NULL to disable - * remote control handling). - * @rc_key_map_size: number of items in @rc_key_map. - * @rc_query: called to query an event event. - * @rc_interval: time in ms between two queries. + * @rc: remote controller properties * * @i2c_algo: i2c_algorithm if the device has I2CoverUSB. * @@ -233,14 +268,11 @@ struct dvb_usb_device_properties { int (*identify_state) (struct usb_device *, struct dvb_usb_device_properties *, struct dvb_usb_device_description **, int *); -/* remote control properties */ -#define REMOTE_NO_KEY_PRESSED 0x00 -#define REMOTE_KEY_PRESSED 0x01 -#define REMOTE_KEY_REPEAT 0x02 - struct dvb_usb_rc_key *rc_key_map; - int rc_key_map_size; - int (*rc_query) (struct dvb_usb_device *, u32 *, int *); - int rc_interval; + struct { + enum dvb_usb_mode mode; /* Drivers shouldn't touch on it */ + struct dvb_rc_legacy legacy; + struct dvb_rc core; + } rc; struct i2c_algorithm *i2c_algo; diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index e8fb85380672..774df88dc6e3 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -74,7 +74,7 @@ "on firmware-problems." struct ir_codes_dvb_usb_table_table { - struct dvb_usb_rc_key *rc_keys; + struct ir_scancode *rc_keys; int rc_keys_size; }; @@ -948,7 +948,7 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) return 0; } -static struct dvb_usb_rc_key ir_codes_dw210x_table[] = { +static struct ir_scancode ir_codes_dw210x_table[] = { { 0xf80a, KEY_Q }, /*power*/ { 0xf80c, KEY_M }, /*mute*/ { 0xf811, KEY_1 }, @@ -982,7 +982,7 @@ static struct dvb_usb_rc_key ir_codes_dw210x_table[] = { { 0xf81b, KEY_B }, /*recall*/ }; -static struct dvb_usb_rc_key ir_codes_tevii_table[] = { +static struct ir_scancode ir_codes_tevii_table[] = { { 0xf80a, KEY_POWER }, { 0xf80c, KEY_MUTE }, { 0xf811, KEY_1 }, @@ -1032,7 +1032,7 @@ static struct dvb_usb_rc_key ir_codes_tevii_table[] = { { 0xf858, KEY_SWITCHVIDEOMODE }, }; -static struct dvb_usb_rc_key ir_codes_tbs_table[] = { +static struct ir_scancode ir_codes_tbs_table[] = { { 0xf884, KEY_POWER }, { 0xf894, KEY_MUTE }, { 0xf887, KEY_1 }, @@ -1075,8 +1075,8 @@ static struct ir_codes_dvb_usb_table_table keys_tables[] = { static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - int keymap_size = d->props.rc_key_map_size; + struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; + int keymap_size = d->props.rc.legacy.rc_key_map_size; u8 key[2]; struct i2c_msg msg = { .addr = DW2102_RC_QUERY, @@ -1096,7 +1096,7 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) for (i = 0; i < keymap_size ; i++) { if (rc5_data(&keymap[i]) == msg.buf[0]) { *state = REMOTE_KEY_PRESSED; - *event = keymap[i].event; + *event = keymap[i].keycode; break; } @@ -1185,13 +1185,13 @@ static int dw2102_load_firmware(struct usb_device *dev, /* init registers */ switch (dev->descriptor.idProduct) { case USB_PID_PROF_1100: - s6x0_properties.rc_key_map = ir_codes_tbs_table; - s6x0_properties.rc_key_map_size = + s6x0_properties.rc.legacy.rc_key_map = ir_codes_tbs_table; + s6x0_properties.rc.legacy.rc_key_map_size = ARRAY_SIZE(ir_codes_tbs_table); break; case USB_PID_TEVII_S650: - dw2104_properties.rc_key_map = ir_codes_tevii_table; - dw2104_properties.rc_key_map_size = + dw2104_properties.rc.legacy.rc_key_map = ir_codes_tevii_table; + dw2104_properties.rc.legacy.rc_key_map_size = ARRAY_SIZE(ir_codes_tevii_table); case USB_PID_DW2104: reset = 1; @@ -1255,10 +1255,13 @@ static struct dvb_usb_device_properties dw2102_properties = { .no_reconnect = 1, .i2c_algo = &dw2102_serit_i2c_algo, - .rc_key_map = ir_codes_dw210x_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table), - .rc_interval = 150, - .rc_query = dw2102_rc_query, + + .rc.legacy = { + .rc_key_map = ir_codes_dw210x_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table), + .rc_interval = 150, + .rc_query = dw2102_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x81, /* parameter for the MPEG2-data transfer */ @@ -1306,10 +1309,12 @@ static struct dvb_usb_device_properties dw2104_properties = { .no_reconnect = 1, .i2c_algo = &dw2104_i2c_algo, - .rc_key_map = ir_codes_dw210x_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table), - .rc_interval = 150, - .rc_query = dw2102_rc_query, + .rc.legacy = { + .rc_key_map = ir_codes_dw210x_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table), + .rc_interval = 150, + .rc_query = dw2102_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x81, /* parameter for the MPEG2-data transfer */ @@ -1353,10 +1358,12 @@ static struct dvb_usb_device_properties dw3101_properties = { .no_reconnect = 1, .i2c_algo = &dw3101_i2c_algo, - .rc_key_map = ir_codes_dw210x_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table), - .rc_interval = 150, - .rc_query = dw2102_rc_query, + .rc.legacy = { + .rc_key_map = ir_codes_dw210x_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table), + .rc_interval = 150, + .rc_query = dw2102_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x81, /* parameter for the MPEG2-data transfer */ @@ -1396,10 +1403,12 @@ static struct dvb_usb_device_properties s6x0_properties = { .no_reconnect = 1, .i2c_algo = &s6x0_i2c_algo, - .rc_key_map = ir_codes_tevii_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_tevii_table), - .rc_interval = 150, - .rc_query = dw2102_rc_query, + .rc.legacy = { + .rc_key_map = ir_codes_tevii_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_tevii_table), + .rc_interval = 150, + .rc_query = dw2102_rc_query, + }, .generic_bulk_ctrl_endpoint = 0x81, .num_adapters = 1, @@ -1459,8 +1468,8 @@ static int dw2102_probe(struct usb_interface *intf, /* fill only different fields */ p7500->firmware = "dvb-usb-p7500.fw"; p7500->devices[0] = d7500; - p7500->rc_key_map = ir_codes_tbs_table; - p7500->rc_key_map_size = ARRAY_SIZE(ir_codes_tbs_table); + p7500->rc.legacy.rc_key_map = ir_codes_tbs_table; + p7500->rc.legacy.rc_key_map_size = ARRAY_SIZE(ir_codes_tbs_table); p7500->adapter->frontend_attach = prof_7500_frontend_attach; if (0 == dvb_usb_device_init(intf, &dw2102_properties, diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c index 7a7f1b2b681c..dbdb5347b2a8 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c +++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c @@ -349,7 +349,7 @@ static struct dvb_frontend_ops gp8psk_fe_ops = { * FE_CAN_QAM_16 is for compatibility * (Myth incorrectly detects Turbo-QPSK as plain QAM-16) */ - FE_CAN_QPSK | FE_CAN_QAM_16 + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_TURBO_FEC }, .release = gp8psk_fe_release, diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c index c211fef45fc3..bdef1a18b664 100644 --- a/drivers/media/dvb/dvb-usb/m920x.c +++ b/drivers/media/dvb/dvb-usb/m920x.c @@ -69,7 +69,7 @@ static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq) int adap_enabled[M9206_MAX_ADAPTERS] = { 0 }; /* Remote controller init. */ - if (d->props.rc_query) { + if (d->props.rc.legacy.rc_query) { deb("Initialising remote control\n"); while (rc_seq->address) { if ((ret = m920x_write(d->udev, M9206_CORE, @@ -142,9 +142,9 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0) goto unlock; - for (i = 0; i < d->props.rc_key_map_size; i++) - if (rc5_data(&d->props.rc_key_map[i]) == rc_state[1]) { - *event = d->props.rc_key_map[i].event; + for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) + if (rc5_data(&d->props.rc.legacy.rc_key_map[i]) == rc_state[1]) { + *event = d->props.rc.legacy.rc_key_map[i].keycode; switch(rc_state[0]) { case 0x80: @@ -589,7 +589,7 @@ static struct m920x_inits pinnacle310e_init[] = { }; /* ir keymaps */ -static struct dvb_usb_rc_key ir_codes_megasky_table [] = { +static struct ir_scancode ir_codes_megasky_table[] = { { 0x0012, KEY_POWER }, { 0x001e, KEY_CYCLEWINDOWS }, /* min/max */ { 0x0002, KEY_CHANNELUP }, @@ -608,7 +608,7 @@ static struct dvb_usb_rc_key ir_codes_megasky_table [] = { { 0x000e, KEY_COFFEE }, /* "MTS" */ }; -static struct dvb_usb_rc_key ir_codes_tvwalkertwin_table [] = { +static struct ir_scancode ir_codes_tvwalkertwin_table[] = { { 0x0001, KEY_ZOOM }, /* Full Screen */ { 0x0002, KEY_CAMERA }, /* snapshot */ { 0x0003, KEY_MUTE }, @@ -628,7 +628,7 @@ static struct dvb_usb_rc_key ir_codes_tvwalkertwin_table [] = { { 0x001e, KEY_VOLUMEUP }, }; -static struct dvb_usb_rc_key ir_codes_pinnacle310e_table[] = { +static struct ir_scancode ir_codes_pinnacle310e_table[] = { { 0x16, KEY_POWER }, { 0x17, KEY_FAVORITES }, { 0x0f, KEY_TEXT }, @@ -784,10 +784,12 @@ static struct dvb_usb_device_properties megasky_properties = { .firmware = "dvb-usb-megasky-02.fw", .download_firmware = m920x_firmware_download, - .rc_interval = 100, - .rc_key_map = ir_codes_megasky_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_megasky_table), - .rc_query = m920x_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_megasky_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_megasky_table), + .rc_query = m920x_rc_query, + }, .size_of_priv = sizeof(struct m920x_state), @@ -885,10 +887,12 @@ static struct dvb_usb_device_properties tvwalkertwin_properties = { .firmware = "dvb-usb-tvwalkert.fw", .download_firmware = m920x_firmware_download, - .rc_interval = 100, - .rc_key_map = ir_codes_tvwalkertwin_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_tvwalkertwin_table), - .rc_query = m920x_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_tvwalkertwin_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_tvwalkertwin_table), + .rc_query = m920x_rc_query, + }, .size_of_priv = sizeof(struct m920x_state), @@ -992,10 +996,12 @@ static struct dvb_usb_device_properties pinnacle_pctv310e_properties = { .usb_ctrl = DEVICE_SPECIFIC, .download_firmware = NULL, - .rc_interval = 100, - .rc_key_map = ir_codes_pinnacle310e_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_pinnacle310e_table), - .rc_query = m920x_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_pinnacle310e_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_pinnacle310e_table), + .rc_query = m920x_rc_query, + }, .size_of_priv = sizeof(struct m920x_state), diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c index d195a587cc65..181f36a12e2a 100644 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -21,7 +21,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define deb_ee(args...) dprintk(debug,0x02,args) /* Hauppauge NOVA-T USB2 keys */ -static struct dvb_usb_rc_key ir_codes_haupp_table [] = { +static struct ir_scancode ir_codes_haupp_table[] = { { 0x1e00, KEY_0 }, { 0x1e01, KEY_1 }, { 0x1e02, KEY_2 }, @@ -98,7 +98,7 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state) deb_rc("c: %x, d: %x\n", rc5_data(&ir_codes_haupp_table[i]), rc5_custom(&ir_codes_haupp_table[i])); - *event = ir_codes_haupp_table[i].event; + *event = ir_codes_haupp_table[i].keycode; *state = REMOTE_KEY_PRESSED; if (st->old_toggle == toggle) { if (st->last_repeat_count++ < 2) @@ -195,10 +195,12 @@ static struct dvb_usb_device_properties nova_t_properties = { .power_ctrl = dibusb2_0_power_ctrl, .read_mac_address = nova_t_read_mac_address, - .rc_interval = 100, - .rc_key_map = ir_codes_haupp_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_haupp_table), - .rc_query = nova_t_rc_query, + .rc.legacy = { + .rc_interval = 100, + .rc_key_map = ir_codes_haupp_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_haupp_table), + .rc_query = nova_t_rc_query, + }, .i2c_algo = &dibusb_i2c_algo, diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c index dfb81ff1d9a7..6b22ec64ab0c 100644 --- a/drivers/media/dvb/dvb-usb/opera1.c +++ b/drivers/media/dvb/dvb-usb/opera1.c @@ -331,7 +331,7 @@ static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff) return 0; } -static struct dvb_usb_rc_key ir_codes_opera1_table[] = { +static struct ir_scancode ir_codes_opera1_table[] = { {0x5fa0, KEY_1}, {0x51af, KEY_2}, {0x5da2, KEY_3}, @@ -407,9 +407,9 @@ static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) for (i = 0; i < ARRAY_SIZE(ir_codes_opera1_table); i++) { if (rc5_scan(&ir_codes_opera1_table[i]) == (send_key & 0xffff)) { *state = REMOTE_KEY_PRESSED; - *event = ir_codes_opera1_table[i].event; + *event = ir_codes_opera1_table[i].keycode; opst->last_key_pressed = - ir_codes_opera1_table[i].event; + ir_codes_opera1_table[i].keycode; break; } opst->last_key_pressed = 0; @@ -498,10 +498,12 @@ static struct dvb_usb_device_properties opera1_properties = { .power_ctrl = opera1_power_ctrl, .i2c_algo = &opera1_i2c_algo, - .rc_key_map = ir_codes_opera1_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_opera1_table), - .rc_interval = 200, - .rc_query = opera1_rc_query, + .rc.legacy = { + .rc_key_map = ir_codes_opera1_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_opera1_table), + .rc_interval = 200, + .rc_query = opera1_rc_query, + }, .read_mac_address = opera1_read_mac_address, .generic_bulk_ctrl_endpoint = 0x00, /* parameter for the MPEG2-data transfer */ diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c index 4d332451653b..5c9f3275aaa0 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.c +++ b/drivers/media/dvb/dvb-usb/vp702x.c @@ -174,7 +174,7 @@ static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) } /* keys for the enclosed remote control */ -static struct dvb_usb_rc_key ir_codes_vp702x_table[] = { +static struct ir_scancode ir_codes_vp702x_table[] = { { 0x0001, KEY_1 }, { 0x0002, KEY_2 }, }; @@ -200,7 +200,7 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) for (i = 0; i < ARRAY_SIZE(ir_codes_vp702x_table); i++) if (rc5_custom(&ir_codes_vp702x_table[i]) == key[1]) { *state = REMOTE_KEY_PRESSED; - *event = ir_codes_vp702x_table[i].event; + *event = ir_codes_vp702x_table[i].keycode; break; } return 0; @@ -283,10 +283,12 @@ static struct dvb_usb_device_properties vp702x_properties = { }, .read_mac_address = vp702x_read_mac_addr, - .rc_key_map = ir_codes_vp702x_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_vp702x_table), - .rc_interval = 400, - .rc_query = vp702x_rc_query, + .rc.legacy = { + .rc_key_map = ir_codes_vp702x_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_vp702x_table), + .rc_interval = 400, + .rc_query = vp702x_rc_query, + }, .num_device_descs = 1, .devices = { diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 036893fa4480..f13791ca5994 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -99,7 +99,7 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff) /* The keymapping struct. Somehow this should be loaded to the driver, but * currently it is hardcoded. */ -static struct dvb_usb_rc_key ir_codes_vp7045_table[] = { +static struct ir_scancode ir_codes_vp7045_table[] = { { 0x0016, KEY_POWER }, { 0x0010, KEY_MUTE }, { 0x0003, KEY_1 }, @@ -168,7 +168,7 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state) for (i = 0; i < ARRAY_SIZE(ir_codes_vp7045_table); i++) if (rc5_data(&ir_codes_vp7045_table[i]) == key) { *state = REMOTE_KEY_PRESSED; - *event = ir_codes_vp7045_table[i].event; + *event = ir_codes_vp7045_table[i].keycode; break; } return 0; @@ -259,10 +259,12 @@ static struct dvb_usb_device_properties vp7045_properties = { .power_ctrl = vp7045_power_ctrl, .read_mac_address = vp7045_read_mac_addr, - .rc_interval = 400, - .rc_key_map = ir_codes_vp7045_table, - .rc_key_map_size = ARRAY_SIZE(ir_codes_vp7045_table), - .rc_query = vp7045_rc_query, + .rc.legacy = { + .rc_interval = 400, + .rc_key_map = ir_codes_vp7045_table, + .rc_key_map_size = ARRAY_SIZE(ir_codes_vp7045_table), + .rc_query = vp7045_rc_query, + }, .num_device_descs = 2, .devices = { |