diff options
Diffstat (limited to 'drivers/media/dvb')
55 files changed, 1295 insertions, 1391 deletions
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index 770243c720d..cf870516284 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c @@ -565,7 +565,7 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct int result = 0; lock_kernel(); - dvbdev = (struct dvb_device *)file->private_data; + dvbdev = file->private_data; state = (struct dst_state *)dvbdev->priv; p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL); p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL); diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 425862ffb28..0042306ea11 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c @@ -207,7 +207,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) } /* TODO */ dvbdev->users--; - if(dvbdev->users==-1 && dmxdev->exit==1) { + if (dvbdev->users == 1 && dmxdev->exit == 1) { fops_put(file->f_op); file->f_op = NULL; mutex_unlock(&dmxdev->mutex); diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index ef259a0718a..cb97e6b8543 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -1318,8 +1318,11 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, fragbuf[0] = connection_id; fragbuf[1] = ((fragpos + fraglen) < count) ? 0x80 : 0x00; - if ((status = copy_from_user(fragbuf + 2, buf + fragpos, fraglen)) != 0) + status = copy_from_user(fragbuf + 2, buf + fragpos, fraglen); + if (status) { + status = -EFAULT; goto exit; + } timeout = jiffies + HZ / 2; written = 0; @@ -1494,8 +1497,11 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, hdr[0] = slot; hdr[1] = connection_id; - if ((status = copy_to_user(buf, hdr, 2)) != 0) + status = copy_to_user(buf, hdr, 2); + if (status) { + status = -EFAULT; goto exit; + } status = pktlen; exit: diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index 977ddba3e23..4a88a3e4db2 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c @@ -1130,13 +1130,9 @@ static int dvbdmx_write(struct dmx_demux *demux, const char __user *buf, size_t if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) return -EINVAL; - p = kmalloc(count, GFP_USER); - if (!p) - return -ENOMEM; - if (copy_from_user(p, buf, count)) { - kfree(p); - return -EFAULT; - } + p = memdup_user(buf, count); + if (IS_ERR(p)) + return PTR_ERR(p); if (mutex_lock_interruptible(&dvbdemux->mutex)) { kfree(p); return -ERESTARTSYS; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 44ae89ecef9..4d45b7d6b3f 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -465,7 +465,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { fepriv->delay = fepriv->min_delay; - /* peform a tune */ + /* perform a tune */ retval = dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped); if (retval < 0) { @@ -791,7 +791,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe) return 0; } -static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe, +static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe, u32 *freq_min, u32 *freq_max) { *freq_min = max(fe->ops.info.frequency_min, fe->ops.tuner_ops.info.frequency_min); @@ -815,7 +815,7 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, u32 freq_max; /* range check: frequency */ - dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max); + dvb_frontend_get_frequency_limits(fe, &freq_min, &freq_max); if ((freq_min && parms->frequency < freq_min) || (freq_max && parms->frequency > freq_max)) { printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n", @@ -1627,7 +1627,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file, case FE_GET_INFO: { struct dvb_frontend_info* info = parg; memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info)); - dvb_frontend_get_frequeny_limits(fe, &info->frequency_min, &info->frequency_max); + dvb_frontend_get_frequency_limits(fe, &info->frequency_min, &info->frequency_max); /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't * do it, it is done for it. */ @@ -1726,7 +1726,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file, * (stv0299 for instance) take longer than 8msec to * respond to a set_voltage command. Those switches * need custom routines to switch properly. For all - * other frontends, the following shoule work ok. + * other frontends, the following should work ok. * Dish network legacy switches (as used by Dish500) * are controlled by sending 9-bit command words * spaced 8msec apart. diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index b6cbb1dfc5f..a5c36372713 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 b41fa873b04..696207fe37e 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 cfd6107d534..8ecba8848bc 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 088e7083a39..3c1fbd1c5d6 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 66c7c3ea799..ea1ed3b4592 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 63b2a4907b7..c8e9349742e 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 faca1ad88a6..4685259e161 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 6681ac1c56e..62c58288469 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 5a9c14bdc98..4f5aa83fc1f 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 11e9e85dac8..cd9f362c37b 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 83fc24a6c31..c2c9d236ec7 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 4f961d2d181..fe818348b8a 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 800800a9649..f634d2e784b 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 bc08bc0b723..ba991aa21af 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 eb2e6f050fb..8e3c0d2cce1 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 588308eb663..1cbc41cb4e8 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 3d50ac59088..61a6bf38947 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 e826077094f..13d006bb19d 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 f57e59044d4..ca495e07f35 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 b4afe6f8ed1..1a774d58d66 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 5d91f70d2d2..2e3ea0fa28e 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 852fe89539c..b579fed3ab3 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 4a9f676087b..34f7b3ba8cc 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 e8fb8538067..774df88dc6e 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 7a7f1b2b681..dbdb5347b2a 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 c211fef45fc..bdef1a18b66 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 d195a587cc6..181f36a12e2 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 dfb81ff1d9a..6b22ec64ab0 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 4d332451653..5c9f3275aaa 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 036893fa448..f13791ca599 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 = { diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index cd7f9b7cbff..51d578a758a 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -584,6 +584,7 @@ config DVB_LGS8GL5 config DVB_LGS8GXX tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator" depends on DVB_CORE && I2C + select FW_LOADER default m if DVB_FE_CUSTOMISE help A DMB-TH tuner module. Say Y when you want to support this frontend. diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index 12e018b4107..dac917f7bb7 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c @@ -1,5 +1,5 @@ /* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver + * Afatech AF9013 demodulator driver * * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> * @@ -761,6 +761,10 @@ static int af9013_set_frontend(struct dvb_frontend *fe, state->frequency = params->frequency; + /* program tuner */ + if (fe->ops.tuner_ops.set_params) + fe->ops.tuner_ops.set_params(fe, params); + /* program CFOE coefficients */ ret = af9013_set_coeff(state, params->u.ofdm.bandwidth); if (ret) @@ -791,10 +795,6 @@ static int af9013_set_frontend(struct dvb_frontend *fe, if (ret) goto error; - /* program tuner */ - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, params); - /* program TPS and bandwidth, check if auto mode needed */ ret = af9013_set_ofdm_params(state, ¶ms->u.ofdm, &auto_mode); if (ret) @@ -1184,45 +1184,49 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) u8 tmp; *status = 0; - /* TPS lock */ - ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; - /* MPEG2 lock */ ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp); if (ret) goto error; if (tmp) - *status |= FE_HAS_SYNC | FE_HAS_LOCK; + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | + FE_HAS_SYNC | FE_HAS_LOCK; - if (!(*status & FE_HAS_SIGNAL)) { - /* AGC lock */ - ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); + if (!*status) { + /* TPS lock */ + ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp); if (ret) goto error; if (tmp) - *status |= FE_HAS_SIGNAL; + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI; } - if (!(*status & FE_HAS_CARRIER)) { + if (!*status) { /* CFO lock */ ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); if (ret) goto error; if (tmp) - *status |= FE_HAS_CARRIER; + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; } - if (!(*status & FE_HAS_CARRIER)) { + if (!*status) { /* SFOE lock */ ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); if (ret) goto error; if (tmp) - *status |= FE_HAS_CARRIER; + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; + } + + if (!*status) { + /* AGC lock */ + ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); + if (ret) + goto error; + if (tmp) + *status |= FE_HAS_SIGNAL; } ret = af9013_update_statistics(fe); @@ -1574,7 +1578,7 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config, { int ret; struct af9013_state *state = NULL; - u8 buf[3], i; + u8 buf[4], i; /* allocate memory for the internal state */ state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL); @@ -1607,12 +1611,12 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config, } /* firmware version */ - for (i = 0; i < 3; i++) { + for (i = 0; i < 4; i++) { ret = af9013_read_reg(state, 0x5103 + i, &buf[i]); if (ret) goto error; } - info("firmware version:%d.%d.%d", buf[0], buf[1], buf[2]); + info("firmware version:%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]); /* settings for mp2if */ if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) { diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h index e90fa92b1c1..72c71bb5d11 100644 --- a/drivers/media/dvb/frontends/af9013.h +++ b/drivers/media/dvb/frontends/af9013.h @@ -1,5 +1,5 @@ /* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver + * Afatech AF9013 demodulator driver * * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> * diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h index 163e251d0b7..0fd42b7e248 100644 --- a/drivers/media/dvb/frontends/af9013_priv.h +++ b/drivers/media/dvb/frontends/af9013_priv.h @@ -1,5 +1,5 @@ /* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver + * Afatech AF9013 demodulator driver * * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> * @@ -132,6 +132,8 @@ static struct regdesc ofsm_init[] = { { 0xd740, 2, 1, 0x00 }, { 0xd740, 3, 1, 0x01 }, { 0xd3c1, 4, 1, 0x01 }, + { 0x9124, 0, 8, 0x58 }, + { 0x9125, 0, 2, 0x02 }, { 0xd3a2, 0, 8, 0x00 }, { 0xd3a3, 0, 8, 0x04 }, { 0xd305, 0, 8, 0x32 }, @@ -143,7 +145,7 @@ static struct regdesc ofsm_init[] = { { 0x911b, 0, 1, 0x01 }, { 0x9bce, 0, 4, 0x02 }, { 0x9116, 0, 1, 0x01 }, - { 0x9bd1, 0, 1, 0x01 }, + { 0x9122, 0, 8, 0xd0 }, { 0xd2e0, 0, 8, 0xd0 }, { 0xd2e9, 0, 4, 0x0d }, { 0xd38c, 0, 8, 0xfc }, @@ -165,7 +167,6 @@ static struct regdesc ofsm_init[] = { { 0xd081, 4, 4, 0x09 }, { 0xd098, 4, 4, 0x0f }, { 0xd098, 0, 4, 0x03 }, - { 0xdbc0, 3, 1, 0x01 }, { 0xdbc0, 4, 1, 0x01 }, { 0xdbc7, 0, 8, 0x08 }, { 0xdbc8, 4, 4, 0x00 }, @@ -179,6 +180,7 @@ static struct regdesc ofsm_init[] = { { 0xd0f0, 0, 7, 0x1a }, { 0xd0f1, 4, 1, 0x01 }, { 0xd0f2, 0, 8, 0x0c }, + { 0xd101, 5, 3, 0x06 }, { 0xd103, 0, 4, 0x08 }, { 0xd0f8, 0, 7, 0x20 }, { 0xd111, 5, 1, 0x00 }, diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c index ad4c8cfd809..e80c5979636 100644 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ b/drivers/media/dvb/frontends/dib3000mb.c @@ -38,11 +38,10 @@ #define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator" #define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de" -#ifdef CONFIG_DVB_DIBCOM_DEBUG static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able))."); -#endif + #define deb_info(args...) dprintk(0x01,args) #define deb_i2c(args...) dprintk(0x02,args) #define deb_srch(args...) dprintk(0x04,args) @@ -51,12 +50,6 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-a #define deb_setf(args...) dprintk(0x04,args) #define deb_getf(args...) dprintk(0x08,args) -#ifdef CONFIG_DVB_DIBCOM_DEBUG -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able))."); -#endif - static int dib3000_read_reg(struct dib3000_state *state, u16 reg) { u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff }; diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h index 1a12747fdc9..16c526591f3 100644 --- a/drivers/media/dvb/frontends/dib3000mb_priv.h +++ b/drivers/media/dvb/frontends/dib3000mb_priv.h @@ -37,12 +37,8 @@ /* debug */ -#ifdef CONFIG_DVB_DIBCOM_DEBUG #define dprintk(level,args...) \ do { if ((debug & level)) { printk(args); } } while (0) -#else -#define dprintk(args...) do { } while (0) -#endif /* mask for enabling a specific pid for the pid_filter */ #define DIB3000_ACTIVATE_PID_FILTERING (0x2000) diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index afad252abf4..088e7fadbe3 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c @@ -822,7 +822,7 @@ int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defa dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL); if (dmcst == NULL) - return -ENODEV; + return -ENOMEM; dmcst->i2c_adap = i2c; diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c index d69c775f864..3272881cb11 100644 --- a/drivers/media/dvb/frontends/lgdt3305.c +++ b/drivers/media/dvb/frontends/lgdt3305.c @@ -1,7 +1,9 @@ /* - * Support for LGDT3305 - VSB/QAM + * Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM * - * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org> + * Copyright (C) 2008, 2009, 2010 Michael Krufky <mkrufky@linuxtv.org> + * + * LGDT3304 support by Jarod Wilson <jarod@redhat.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -65,6 +67,8 @@ struct lgdt3305_state { /* ------------------------------------------------------------------------ */ +/* FIXME: verify & document the LGDT3304 registers */ + #define LGDT3305_GEN_CTRL_1 0x0000 #define LGDT3305_GEN_CTRL_2 0x0001 #define LGDT3305_GEN_CTRL_3 0x0002 @@ -358,7 +362,12 @@ static int lgdt3305_rfagc_loop(struct lgdt3305_state *state, case QAM_256: agcdelay = 0x046b; rfbw = 0x8889; - ifbw = 0x8888; + /* FIXME: investigate optimal ifbw & rfbw values for the + * DT3304 and re-write this switch..case block */ + if (state->cfg->demod_chip == LGDT3304) + ifbw = 0x6666; + else /* (state->cfg->demod_chip == LGDT3305) */ + ifbw = 0x8888; break; default: return -EINVAL; @@ -410,8 +419,18 @@ static int lgdt3305_agc_setup(struct lgdt3305_state *state, lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen); /* control agc function */ - lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1); - lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen); + switch (state->cfg->demod_chip) { + case LGDT3304: + lgdt3305_write_reg(state, 0x0314, 0xe1 | lockdten << 1); + lgdt3305_set_reg_bit(state, 0x030e, 2, acqen); + break; + case LGDT3305: + lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1); + lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen); + break; + default: + return -EINVAL; + } return lgdt3305_rfagc_loop(state, param); } @@ -577,61 +596,79 @@ static int lgdt3305_init(struct dvb_frontend *fe) struct lgdt3305_state *state = fe->demodulator_priv; int ret; + static struct lgdt3305_reg lgdt3304_init_data[] = { + { .reg = LGDT3305_GEN_CTRL_1, .val = 0x03, }, + { .reg = 0x000d, .val = 0x02, }, + { .reg = 0x000e, .val = 0x02, }, + { .reg = LGDT3305_DGTL_AGC_REF_1, .val = 0x32, }, + { .reg = LGDT3305_DGTL_AGC_REF_2, .val = 0xc4, }, + { .reg = LGDT3305_CR_CTR_FREQ_1, .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_2, .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_3, .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_4, .val = 0x00, }, + { .reg = LGDT3305_CR_CTRL_7, .val = 0xf9, }, + { .reg = 0x0112, .val = 0x17, }, + { .reg = 0x0113, .val = 0x15, }, + { .reg = 0x0114, .val = 0x18, }, + { .reg = 0x0115, .val = 0xff, }, + { .reg = 0x0116, .val = 0x3c, }, + { .reg = 0x0214, .val = 0x67, }, + { .reg = 0x0424, .val = 0x8d, }, + { .reg = 0x0427, .val = 0x12, }, + { .reg = 0x0428, .val = 0x4f, }, + { .reg = LGDT3305_IFBW_1, .val = 0x80, }, + { .reg = LGDT3305_IFBW_2, .val = 0x00, }, + { .reg = 0x030a, .val = 0x08, }, + { .reg = 0x030b, .val = 0x9b, }, + { .reg = 0x030d, .val = 0x00, }, + { .reg = 0x030e, .val = 0x1c, }, + { .reg = 0x0314, .val = 0xe1, }, + { .reg = 0x000d, .val = 0x82, }, + { .reg = LGDT3305_TP_CTRL_1, .val = 0x5b, }, + { .reg = LGDT3305_TP_CTRL_1, .val = 0x5b, }, + }; + static struct lgdt3305_reg lgdt3305_init_data[] = { - { .reg = LGDT3305_GEN_CTRL_1, - .val = 0x03, }, - { .reg = LGDT3305_GEN_CTRL_2, - .val = 0xb0, }, - { .reg = LGDT3305_GEN_CTRL_3, - .val = 0x01, }, - { .reg = LGDT3305_GEN_CONTROL, - .val = 0x6f, }, - { .reg = LGDT3305_GEN_CTRL_4, - .val = 0x03, }, - { .reg = LGDT3305_DGTL_AGC_REF_1, - .val = 0x32, }, - { .reg = LGDT3305_DGTL_AGC_REF_2, - .val = 0xc4, }, - { .reg = LGDT3305_CR_CTR_FREQ_1, - .val = 0x00, }, - { .reg = LGDT3305_CR_CTR_FREQ_2, - .val = 0x00, }, - { .reg = LGDT3305_CR_CTR_FREQ_3, - .val = 0x00, }, - { .reg = LGDT3305_CR_CTR_FREQ_4, - .val = 0x00, }, - { .reg = LGDT3305_CR_CTRL_7, - .val = 0x79, }, - { .reg = LGDT3305_AGC_POWER_REF_1, - .val = 0x32, }, - { .reg = LGDT3305_AGC_POWER_REF_2, - .val = 0xc4, }, - { .reg = LGDT3305_AGC_DELAY_PT_1, - .val = 0x0d, }, - { .reg = LGDT3305_AGC_DELAY_PT_2, - .val = 0x30, }, - { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1, - .val = 0x80, }, - { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2, - .val = 0x00, }, - { .reg = LGDT3305_IFBW_1, - .val = 0x80, }, - { .reg = LGDT3305_IFBW_2, - .val = 0x00, }, - { .reg = LGDT3305_AGC_CTRL_1, - .val = 0x30, }, - { .reg = LGDT3305_AGC_CTRL_4, - .val = 0x61, }, - { .reg = LGDT3305_FEC_BLOCK_CTRL, - .val = 0xff, }, - { .reg = LGDT3305_TP_CTRL_1, - .val = 0x1b, }, + { .reg = LGDT3305_GEN_CTRL_1, .val = 0x03, }, + { .reg = LGDT3305_GEN_CTRL_2, .val = 0xb0, }, + { .reg = LGDT3305_GEN_CTRL_3, .val = 0x01, }, + { .reg = LGDT3305_GEN_CONTROL, .val = 0x6f, }, + { .reg = LGDT3305_GEN_CTRL_4, .val = 0x03, }, + { .reg = LGDT3305_DGTL_AGC_REF_1, .val = 0x32, }, + { .reg = LGDT3305_DGTL_AGC_REF_2, .val = 0xc4, }, + { .reg = LGDT3305_CR_CTR_FREQ_1, .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_2, .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_3, .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_4, .val = 0x00, }, + { .reg = LGDT3305_CR_CTRL_7, .val = 0x79, }, + { .reg = LGDT3305_AGC_POWER_REF_1, .val = 0x32, }, + { .reg = LGDT3305_AGC_POWER_REF_2, .val = 0xc4, }, + { .reg = LGDT3305_AGC_DELAY_PT_1, .val = 0x0d, }, + { .reg = LGDT3305_AGC_DELAY_PT_2, .val = 0x30, }, + { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1, .val = 0x80, }, + { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2, .val = 0x00, }, + { .reg = LGDT3305_IFBW_1, .val = 0x80, }, + { .reg = LGDT3305_IFBW_2, .val = 0x00, }, + { .reg = LGDT3305_AGC_CTRL_1, .val = 0x30, }, + { .reg = LGDT3305_AGC_CTRL_4, .val = 0x61, }, + { .reg = LGDT3305_FEC_BLOCK_CTRL, .val = 0xff, }, + { .reg = LGDT3305_TP_CTRL_1, .val = 0x1b, }, }; lg_dbg("\n"); - ret = lgdt3305_write_regs(state, lgdt3305_init_data, - ARRAY_SIZE(lgdt3305_init_data)); + switch (state->cfg->demod_chip) { + case LGDT3304: + ret = lgdt3305_write_regs(state, lgdt3304_init_data, + ARRAY_SIZE(lgdt3304_init_data)); + break; + case LGDT3305: + ret = lgdt3305_write_regs(state, lgdt3305_init_data, + ARRAY_SIZE(lgdt3305_init_data)); + break; + default: + ret = -EINVAL; + } if (lg_fail(ret)) goto fail; @@ -640,6 +677,76 @@ fail: return ret; } +static int lgdt3304_set_parameters(struct dvb_frontend *fe, + struct dvb_frontend_parameters *param) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + int ret; + + lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation); + + if (fe->ops.tuner_ops.set_params) { + ret = fe->ops.tuner_ops.set_params(fe, param); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + if (lg_fail(ret)) + goto fail; + state->current_frequency = param->frequency; + } + + ret = lgdt3305_set_modulation(state, param); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_passband_digital_agc(state, param); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_agc_setup(state, param); + if (lg_fail(ret)) + goto fail; + + /* reg 0x030d is 3304-only... seen in vsb and qam usbsnoops... */ + switch (param->u.vsb.modulation) { + case VSB_8: + lgdt3305_write_reg(state, 0x030d, 0x00); + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, 0x4f); + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, 0x0c); + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, 0xac); + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, 0xba); + break; + case QAM_64: + case QAM_256: + lgdt3305_write_reg(state, 0x030d, 0x14); + ret = lgdt3305_set_if(state, param); + if (lg_fail(ret)) + goto fail; + break; + default: + return -EINVAL; + } + + + ret = lgdt3305_spectral_inversion(state, param, + state->cfg->spectral_inversion + ? 1 : 0); + if (lg_fail(ret)) + goto fail; + + state->current_modulation = param->u.vsb.modulation; + + ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode); + if (lg_fail(ret)) + goto fail; + + /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */ + ret = lgdt3305_mpeg_mode_polarity(state, + state->cfg->tpclk_edge, + state->cfg->tpvalid_polarity); +fail: + return ret; +} + static int lgdt3305_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { @@ -848,6 +955,10 @@ static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status) switch (state->current_modulation) { case QAM_256: case QAM_64: + /* signal bit is unreliable on the DT3304 in QAM mode */ + if (((LGDT3304 == state->cfg->demod_chip)) && (cr_lock)) + *status |= FE_HAS_SIGNAL; + ret = lgdt3305_read_fec_lock_status(state, &fec_lock); if (lg_fail(ret)) goto fail; @@ -993,6 +1104,7 @@ static void lgdt3305_release(struct dvb_frontend *fe) kfree(state); } +static struct dvb_frontend_ops lgdt3304_ops; static struct dvb_frontend_ops lgdt3305_ops; struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, @@ -1013,11 +1125,21 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, state->cfg = config; state->i2c_adap = i2c_adap; - memcpy(&state->frontend.ops, &lgdt3305_ops, - sizeof(struct dvb_frontend_ops)); + switch (config->demod_chip) { + case LGDT3304: + memcpy(&state->frontend.ops, &lgdt3304_ops, + sizeof(struct dvb_frontend_ops)); + break; + case LGDT3305: + memcpy(&state->frontend.ops, &lgdt3305_ops, + sizeof(struct dvb_frontend_ops)); + break; + default: + goto fail; + } state->frontend.demodulator_priv = state; - /* verify that we're talking to a lg dt3305 */ + /* verify that we're talking to a lg dt3304/5 */ ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val); if ((lg_fail(ret)) | (val == 0)) goto fail; @@ -1036,12 +1158,35 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, return &state->frontend; fail: - lg_warn("unable to detect LGDT3305 hardware\n"); + lg_warn("unable to detect %s hardware\n", + config->demod_chip ? "LGDT3304" : "LGDT3305"); kfree(state); return NULL; } EXPORT_SYMBOL(lgdt3305_attach); +static struct dvb_frontend_ops lgdt3304_ops = { + .info = { + .name = "LG Electronics LGDT3304 VSB/QAM Frontend", + .type = FE_ATSC, + .frequency_min = 54000000, + .frequency_max = 858000000, + .frequency_stepsize = 62500, + .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB + }, + .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl, + .init = lgdt3305_init, + .set_frontend = lgdt3304_set_parameters, + .get_frontend = lgdt3305_get_frontend, + .get_tune_settings = lgdt3305_get_tune_settings, + .read_status = lgdt3305_read_status, + .read_ber = lgdt3305_read_ber, + .read_signal_strength = lgdt3305_read_signal_strength, + .read_snr = lgdt3305_read_snr, + .read_ucblocks = lgdt3305_read_ucblocks, + .release = lgdt3305_release, +}; + static struct dvb_frontend_ops lgdt3305_ops = { .info = { .name = "LG Electronics LGDT3305 VSB/QAM Frontend", @@ -1065,10 +1210,10 @@ static struct dvb_frontend_ops lgdt3305_ops = { .release = lgdt3305_release, }; -MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver"); +MODULE_DESCRIPTION("LG Electronics LGDT3304/5 ATSC/QAM-B Demodulator Driver"); MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1"); +MODULE_VERSION("0.2"); /* * Local variables: diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h index 9cb11c9cae5..02172eca4d4 100644 --- a/drivers/media/dvb/frontends/lgdt3305.h +++ b/drivers/media/dvb/frontends/lgdt3305.h @@ -1,7 +1,7 @@ /* - * Support for LGDT3305 - VSB/QAM + * Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM * - * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org> + * Copyright (C) 2008, 2009, 2010 Michael Krufky <mkrufky@linuxtv.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,6 +41,11 @@ enum lgdt3305_tp_valid_polarity { LGDT3305_TP_VALID_HIGH = 1, }; +enum lgdt_demod_chip_type { + LGDT3305 = 0, + LGDT3304 = 1, +}; + struct lgdt3305_config { u8 i2c_addr; @@ -65,6 +70,7 @@ struct lgdt3305_config { enum lgdt3305_mpeg_mode mpeg_mode; enum lgdt3305_tp_clock_edge tpclk_edge; enum lgdt3305_tp_valid_polarity tpvalid_polarity; + enum lgdt_demod_chip_type demod_chip; }; #if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \ diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c index dee53960e7e..5ea28ae2ba8 100644 --- a/drivers/media/dvb/frontends/lgs8gxx.c +++ b/drivers/media/dvb/frontends/lgs8gxx.c @@ -24,6 +24,7 @@ */ #include <asm/div64.h> +#include <linux/firmware.h> #include "dvb_frontend.h" @@ -46,42 +47,6 @@ module_param(fake_signal_str, int, 0644); MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913." "Signal strength calculation is slow.(default:on)."); -static const u8 lgs8g75_initdat[] = { - 0x01, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xE4, 0xF5, 0xA8, 0xF5, 0xB8, 0xF5, 0x88, 0xF5, - 0x89, 0xF5, 0x87, 0x75, 0xD0, 0x00, 0x11, 0x50, - 0x11, 0x50, 0xF4, 0xF5, 0x80, 0xF5, 0x90, 0xF5, - 0xA0, 0xF5, 0xB0, 0x75, 0x81, 0x30, 0x80, 0x01, - 0x32, 0x90, 0x80, 0x12, 0x74, 0xFF, 0xF0, 0x90, - 0x80, 0x13, 0x74, 0x1F, 0xF0, 0x90, 0x80, 0x23, - 0x74, 0x01, 0xF0, 0x90, 0x80, 0x22, 0xF0, 0x90, - 0x00, 0x48, 0x74, 0x00, 0xF0, 0x90, 0x80, 0x4D, - 0x74, 0x05, 0xF0, 0x90, 0x80, 0x09, 0xE0, 0x60, - 0x21, 0x12, 0x00, 0xDD, 0x14, 0x60, 0x1B, 0x12, - 0x00, 0xDD, 0x14, 0x60, 0x15, 0x12, 0x00, 0xDD, - 0x14, 0x60, 0x0F, 0x12, 0x00, 0xDD, 0x14, 0x60, - 0x09, 0x12, 0x00, 0xDD, 0x14, 0x60, 0x03, 0x12, - 0x00, 0xDD, 0x90, 0x80, 0x42, 0xE0, 0x60, 0x0B, - 0x14, 0x60, 0x0C, 0x14, 0x60, 0x0D, 0x14, 0x60, - 0x0E, 0x01, 0xB3, 0x74, 0x04, 0x01, 0xB9, 0x74, - 0x05, 0x01, 0xB9, 0x74, 0x07, 0x01, 0xB9, 0x74, - 0x0A, 0xC0, 0xE0, 0x74, 0xC8, 0x12, 0x00, 0xE2, - 0xD0, 0xE0, 0x14, 0x70, 0xF4, 0x90, 0x80, 0x09, - 0xE0, 0x70, 0xAE, 0x12, 0x00, 0xF6, 0x12, 0x00, - 0xFE, 0x90, 0x00, 0x48, 0xE0, 0x04, 0xF0, 0x90, - 0x80, 0x4E, 0xF0, 0x01, 0x73, 0x90, 0x80, 0x08, - 0xF0, 0x22, 0xF8, 0x7A, 0x0C, 0x79, 0xFD, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, - 0xF6, 0xDA, 0xF2, 0xD8, 0xEE, 0x22, 0x90, 0x80, - 0x65, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x80, - 0x65, 0xE0, 0x44, 0xC2, 0xF0, 0x22 -}; - /* LGS8GXX internal helper functions */ static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data) @@ -627,9 +592,14 @@ static int lgs8913_init(struct lgs8gxx_state *priv) static int lgs8g75_init_data(struct lgs8gxx_state *priv) { - const u8 *p = lgs8g75_initdat; + const struct firmware *fw; + int rc; int i; + rc = request_firmware(&fw, "lgs8g75.fw", &priv->i2c->dev); + if (rc) + return rc; + lgs8gxx_write_reg(priv, 0xC6, 0x40); lgs8gxx_write_reg(priv, 0x3D, 0x04); @@ -640,16 +610,16 @@ static int lgs8g75_init_data(struct lgs8gxx_state *priv) lgs8gxx_write_reg(priv, 0x3B, 0x00); lgs8gxx_write_reg(priv, 0x38, 0x00); - for (i = 0; i < sizeof(lgs8g75_initdat); i++) { + for (i = 0; i < fw->size; i++) { lgs8gxx_write_reg(priv, 0x38, 0x00); lgs8gxx_write_reg(priv, 0x3A, (u8)(i&0xff)); lgs8gxx_write_reg(priv, 0x3B, (u8)(i>>8)); - lgs8gxx_write_reg(priv, 0x3C, *p); - p++; + lgs8gxx_write_reg(priv, 0x3C, fw->data[i]); } lgs8gxx_write_reg(priv, 0x38, 0x00); + release_firmware(fw); return 0; } diff --git a/drivers/media/dvb/frontends/mb86a16.c b/drivers/media/dvb/frontends/mb86a16.c index 599d1aa519a..33b63235b86 100644 --- a/drivers/media/dvb/frontends/mb86a16.c +++ b/drivers/media/dvb/frontends/mb86a16.c @@ -1833,7 +1833,6 @@ static struct dvb_frontend_ops mb86a16_ops = { .get_frontend_algo = mb86a16_frontend_algo, .search = mb86a16_search, - .read_status = mb86a16_read_status, .init = mb86a16_init, .sleep = mb86a16_sleep, .read_status = mb86a16_read_status, diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 4e2a7c8b2f6..93f6a75c238 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c @@ -25,6 +25,7 @@ #include <linux/string.h> #include <linux/slab.h> #include <linux/delay.h> +#include <linux/math64.h> #include <asm/div64.h> #include "dvb_frontend.h" #include "dvb_math.h" @@ -49,8 +50,8 @@ #define TDA10048_CONF_C4_1 0x1E #define TDA10048_CONF_C4_2 0x1F #define TDA10048_CODE_IN_RAM 0x20 -#define TDA10048_CHANNEL_INFO_1_R 0x22 -#define TDA10048_CHANNEL_INFO_2_R 0x23 +#define TDA10048_CHANNEL_INFO1_R 0x22 +#define TDA10048_CHANNEL_INFO2_R 0x23 #define TDA10048_CHANNEL_INFO1 0x24 #define TDA10048_CHANNEL_INFO2 0x25 #define TDA10048_TIME_ERROR_R 0x26 @@ -63,8 +64,8 @@ #define TDA10048_IT_STAT 0x32 #define TDA10048_DSP_AD_LSB 0x3C #define TDA10048_DSP_AD_MSB 0x3D -#define TDA10048_DSP_REF_LSB 0x3E -#define TDA10048_DSP_REF_MSB 0x3F +#define TDA10048_DSP_REG_LSB 0x3E +#define TDA10048_DSP_REG_MSB 0x3F #define TDA10048_CONF_TRISTATE1 0x44 #define TDA10048_CONF_TRISTATE2 0x45 #define TDA10048_CONF_POLARITY 0x46 @@ -112,7 +113,7 @@ #define TDA10048_FREE_REG_1 0xB2 #define TDA10048_FREE_REG_2 0xB3 #define TDA10048_CONF_C3_1 0xC0 -#define TDA10048_CYBER_CTRL 0xC2 +#define TDA10048_CVBER_CTRL 0xC2 #define TDA10048_CBER_NMAX_LSB 0xC4 #define TDA10048_CBER_NMAX_MSB 0xC5 #define TDA10048_CBER_LSB 0xC6 @@ -120,7 +121,7 @@ #define TDA10048_VBER_LSB 0xC8 #define TDA10048_VBER_MID 0xC9 #define TDA10048_VBER_MSB 0xCA -#define TDA10048_CYBER_LUT 0xCC +#define TDA10048_CVBER_LUT 0xCC #define TDA10048_UNCOR_CTRL 0xCD #define TDA10048_UNCOR_CPT_LSB 0xCE #define TDA10048_UNCOR_CPT_MSB 0xCF @@ -183,7 +184,7 @@ static struct init_tab { { TDA10048_AGC_IF_MAX, 0xff }, { TDA10048_AGC_THRESHOLD_MSB, 0x00 }, { TDA10048_AGC_THRESHOLD_LSB, 0x70 }, - { TDA10048_CYBER_CTRL, 0x38 }, + { TDA10048_CVBER_CTRL, 0x38 }, { TDA10048_AGC_GAINS, 0x12 }, { TDA10048_CONF_XO, 0x00 }, { TDA10048_CONF_TS1, 0x07 }, @@ -688,7 +689,7 @@ static int tda10048_get_tps(struct tda10048_state *state, p->guard_interval = GUARD_INTERVAL_1_4; break; } - switch (val & 0x02) { + switch (val & 0x03) { case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break; @@ -765,6 +766,8 @@ static int tda10048_set_frontend(struct dvb_frontend *fe, /* Enable demod TPS auto detection and begin acquisition */ tda10048_writereg(state, TDA10048_AUTO, 0x57); + /* trigger cber and vber acquisition */ + tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x3B); return 0; } @@ -830,12 +833,27 @@ static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status) static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber) { struct tda10048_state *state = fe->demodulator_priv; + static u32 cber_current; + u32 cber_nmax; + u64 cber_tmp; dprintk(1, "%s()\n", __func__); - /* TODO: A reset may be required here */ - *ber = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 | - tda10048_readreg(state, TDA10048_CBER_LSB); + /* update cber on interrupt */ + if (tda10048_readreg(state, TDA10048_SOFT_IT_C3) & 0x01) { + cber_tmp = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 | + tda10048_readreg(state, TDA10048_CBER_LSB); + cber_nmax = tda10048_readreg(state, TDA10048_CBER_NMAX_MSB) << 8 | + tda10048_readreg(state, TDA10048_CBER_NMAX_LSB); + cber_tmp *= 100000000; + cber_tmp *= 2; + cber_tmp = div_u64(cber_tmp, (cber_nmax * 32) + 1); + cber_current = (u32)cber_tmp; + /* retrigger cber acquisition */ + tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x39); + } + /* actual cber is (*ber)/1e8 */ + *ber = cber_current; return 0; } @@ -1015,6 +1033,9 @@ static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) *ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 | tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB); + /* clear the uncorrected TS packets counter when saturated */ + if (*ucblocks == 0xFFFF) + tda10048_writereg(state, TDA10048_UNCOR_CTRL, 0x80); return 0; } diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig index f7b72a32adf..decdeda840d 100644 --- a/drivers/media/dvb/mantis/Kconfig +++ b/drivers/media/dvb/mantis/Kconfig @@ -10,9 +10,15 @@ config MANTIS_CORE config DVB_MANTIS tristate "MANTIS based cards" depends on MANTIS_CORE && DVB_CORE && PCI && I2C - select DVB_MB86A16 - select DVB_ZL10353 - select DVB_STV0299 + select DVB_MB86A16 if !DVB_FE_CUSTOMISE + select DVB_ZL10353 if !DVB_FE_CUSTOMISE + select DVB_STV0299 if !DVB_FE_CUSTOMISE + select DVB_LNBP21 if !DVB_FE_CUSTOMISE + select DVB_STB0899 if !DVB_FE_CUSTOMISE + select DVB_STB6100 if !DVB_FE_CUSTOMISE + select DVB_TDA665x if !DVB_FE_CUSTOMISE + select DVB_TDA10021 if !DVB_FE_CUSTOMISE + select DVB_TDA10023 if !DVB_FE_CUSTOMISE select DVB_PLL help Support for PCI cards based on the Mantis PCI bridge. @@ -23,7 +29,7 @@ config DVB_MANTIS config DVB_HOPPER tristate "HOPPER based cards" depends on MANTIS_CORE && DVB_CORE && PCI && I2C - select DVB_ZL10353 + select DVB_ZL10353 if !DVB_FE_CUSTOMISE select DVB_PLL help Support for PCI cards based on the Hopper PCI bridge. diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c index 3d4e4663220..a99489b8418 100644 --- a/drivers/media/dvb/mantis/mantis_input.c +++ b/drivers/media/dvb/mantis/mantis_input.c @@ -19,7 +19,7 @@ */ #include <linux/input.h> -#include <media/ir-common.h> +#include <media/ir-core.h> #include <linux/pci.h> #include "dmxdev.h" @@ -104,7 +104,6 @@ EXPORT_SYMBOL_GPL(ir_mantis); int mantis_input_init(struct mantis_pci *mantis) { struct input_dev *rc; - struct ir_input_state rc_state; char name[80], dev[80]; int err; @@ -120,8 +119,6 @@ int mantis_input_init(struct mantis_pci *mantis) rc->name = name; rc->phys = dev; - ir_input_init(rc, &rc_state, IR_TYPE_OTHER); - rc->id.bustype = BUS_PCI; rc->id.vendor = mantis->vendor_id; rc->id.product = mantis->device_id; diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index cff77e2eb55..25b43e587fa 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -64,9 +64,11 @@ static struct sms_board sms_boards[] = { .type = SMS_NOVA_B0, .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw", .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", + .rc_codes = RC_MAP_RC5_HAUPPAUGE_NEW, .board_cfg.leds_power = 26, .board_cfg.led0 = 27, .board_cfg.led1 = 28, + .board_cfg.ir = 9, .led_power = 26, .led_lo = 27, .led_hi = 28, diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index 8f19fc000b4..d8cdf756f7c 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h @@ -75,7 +75,7 @@ struct sms_board { enum sms_device_type_st type; char *name, *fw[DEVICE_MODE_MAX]; struct sms_board_gpio_cfg board_cfg; - enum ir_kb_type ir_kb_type; + char *rc_codes; /* Name of IR codes table */ /* gpios */ int led_power, led_hi, led_lo, lna_ctrl, rf_switch; diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 0c87a3c3899..828bcc2e129 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -116,9 +116,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath) return entry; } } - entry = (struct smscore_registry_entry_t *) - kmalloc(sizeof(struct smscore_registry_entry_t), - GFP_KERNEL); + entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL); if (entry) { entry->mode = default_mode; strcpy(entry->devpath, devpath); diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c index a56eac76e0f..d0e4639ee9d 100644 --- a/drivers/media/dvb/siano/smsir.c +++ b/drivers/media/dvb/siano/smsir.c @@ -4,6 +4,11 @@ MDTV receiver kernel modules. Copyright (C) 2006-2009, Uri Shkolnik + Copyright (c) 2010 - Mauro Carvalho Chehab + - Ported the driver to use rc-core + - IR raw event decoding is now done at rc-core + - Code almost re-written + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or @@ -27,226 +32,28 @@ #include "smsir.h" #include "sms-cards.h" -/* In order to add new IR remote control - - * 1) Add it to the <enum ir_kb_type> @ smsir,h, - * 2) Add its map to keyboard_layout_maps below - * 3) Set your board (sms-cards sub-module) to use it - */ - -static struct keyboard_layout_map_t keyboard_layout_maps[] = { - [SMS_IR_KB_DEFAULT_TV] = { - .ir_protocol = IR_RC5, - .rc5_kbd_address = KEYBOARD_ADDRESS_TV1, - .keyboard_layout_map = { - KEY_0, KEY_1, KEY_2, - KEY_3, KEY_4, KEY_5, - KEY_6, KEY_7, KEY_8, - KEY_9, 0, 0, KEY_POWER, - KEY_MUTE, 0, 0, - KEY_VOLUMEUP, KEY_VOLUMEDOWN, - KEY_BRIGHTNESSUP, - KEY_BRIGHTNESSDOWN, KEY_CHANNELUP, - KEY_CHANNELDOWN, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - [SMS_IR_KB_HCW_SILVER] = { - .ir_protocol = IR_RC5, - .rc5_kbd_address = KEYBOARD_ADDRESS_LIGHTING1, - .keyboard_layout_map = { - KEY_0, KEY_1, KEY_2, - KEY_3, KEY_4, KEY_5, - KEY_6, KEY_7, KEY_8, - KEY_9, KEY_TEXT, KEY_RED, - KEY_RADIO, KEY_MENU, - KEY_SUBTITLE, - KEY_MUTE, KEY_VOLUMEUP, - KEY_VOLUMEDOWN, KEY_PREVIOUS, 0, - KEY_UP, KEY_DOWN, KEY_LEFT, - KEY_RIGHT, KEY_VIDEO, KEY_AUDIO, - KEY_MHP, KEY_EPG, KEY_TV, - 0, KEY_NEXTSONG, KEY_EXIT, - KEY_CHANNELUP, KEY_CHANNELDOWN, - KEY_CHANNEL, 0, - KEY_PREVIOUSSONG, KEY_ENTER, - KEY_SLEEP, 0, 0, KEY_BLUE, - 0, 0, 0, 0, KEY_GREEN, 0, - KEY_PAUSE, 0, KEY_REWIND, - 0, KEY_FASTFORWARD, KEY_PLAY, - KEY_STOP, KEY_RECORD, - KEY_YELLOW, 0, 0, KEY_SELECT, - KEY_ZOOM, KEY_POWER, 0, 0 - } - }, - { } /* Terminating entry */ -}; - -static u32 ir_pos; -static u32 ir_word; -static u32 ir_toggle; - -#define RC5_PUSH_BIT(dst, bit, pos) \ - { dst <<= 1; dst |= bit; pos++; } - - -static void sms_ir_rc5_event(struct smscore_device_t *coredev, - u32 toggle, u32 addr, u32 cmd) -{ - bool toggle_changed; - u16 keycode; - - sms_log("IR RC5 word: address %d, command %d, toggle %d", - addr, cmd, toggle); - - toggle_changed = ir_toggle != toggle; - /* keep toggle */ - ir_toggle = toggle; - - if (addr != - keyboard_layout_maps[coredev->ir.ir_kb_type].rc5_kbd_address) - return; /* Check for valid address */ - - keycode = - keyboard_layout_maps - [coredev->ir.ir_kb_type].keyboard_layout_map[cmd]; +#define MODULE_NAME "smsmdtv" - if (!toggle_changed && - (keycode != KEY_VOLUMEUP && keycode != KEY_VOLUMEDOWN)) - return; /* accept only repeated volume, reject other keys */ - - sms_log("kernel input keycode (from ir) %d", keycode); - input_report_key(coredev->ir.input_dev, keycode, 1); - input_sync(coredev->ir.input_dev); - -} - -/* decode raw bit pattern to RC5 code */ -/* taken from ir-functions.c */ -static u32 ir_rc5_decode(unsigned int code) +void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) { -/* unsigned int org_code = code;*/ - unsigned int pair; - unsigned int rc5 = 0; int i; + const s32 *samples = (const void *)buf; - for (i = 0; i < 14; ++i) { - pair = code & 0x3; - code >>= 2; - - rc5 <<= 1; - switch (pair) { - case 0: - case 2: - break; - case 1: - rc5 |= 1; - break; - case 3: -/* dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);*/ - sms_log("bad code"); - return 0; - } - } -/* - dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, - toggle=%x, address=%x, " - "instr=%x\n", rc5, org_code, RC5_START(rc5), - RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); -*/ - return rc5; -} - -static void sms_rc5_parse_word(struct smscore_device_t *coredev) -{ - #define RC5_START(x) (((x)>>12)&3) - #define RC5_TOGGLE(x) (((x)>>11)&1) - #define RC5_ADDR(x) (((x)>>6)&0x1F) - #define RC5_INSTR(x) ((x)&0x3F) - - int i, j; - u32 rc5_word = 0; - - /* Reverse the IR word direction */ - for (i = 0 ; i < 28 ; i++) - RC5_PUSH_BIT(rc5_word, (ir_word>>i)&1, j) - - rc5_word = ir_rc5_decode(rc5_word); - /* sms_log("temp = 0x%x, rc5_code = 0x%x", ir_word, rc5_word); */ - - sms_ir_rc5_event(coredev, - RC5_TOGGLE(rc5_word), - RC5_ADDR(rc5_word), - RC5_INSTR(rc5_word)); -} - - -static void sms_rc5_accumulate_bits(struct smscore_device_t *coredev, - s32 ir_sample) -{ - #define RC5_TIME_GRANULARITY 200 - #define RC5_DEF_BIT_TIME 889 - #define RC5_MAX_SAME_BIT_CONT 4 - #define RC5_WORD_LEN 27 /* 28 bit */ - - u32 i, j; - s32 delta_time; - u32 time = (ir_sample > 0) ? ir_sample : (0-ir_sample); - u32 level = (ir_sample < 0) ? 0 : 1; - - for (i = RC5_MAX_SAME_BIT_CONT; i > 0; i--) { - delta_time = time - (i*RC5_DEF_BIT_TIME) + RC5_TIME_GRANULARITY; - if (delta_time < 0) - continue; /* not so many consecutive bits */ - if (delta_time > (2 * RC5_TIME_GRANULARITY)) { - /* timeout */ - if (ir_pos == (RC5_WORD_LEN-1)) - /* complete last bit */ - RC5_PUSH_BIT(ir_word, level, ir_pos) - - if (ir_pos == RC5_WORD_LEN) - sms_rc5_parse_word(coredev); - else if (ir_pos) /* timeout within a word */ - sms_log("IR error parsing a word"); + for (i = 0; i < len >> 2; i++) { + struct ir_raw_event ev; - ir_pos = 0; - ir_word = 0; - /* sms_log("timeout %d", time); */ - break; - } - /* The time is within the range of this number of bits */ - for (j = 0 ; j < i ; j++) - RC5_PUSH_BIT(ir_word, level, ir_pos) + ev.duration = abs(samples[i]) * 1000; /* Convert to ns */ + ev.pulse = (samples[i] > 0) ? false : true; - break; + ir_raw_event_store(coredev->ir.input_dev, &ev); } -} - -void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) -{ - #define IR_DATA_RECEIVE_MAX_LEN 520 /* 128*4 + 4 + 4 */ - u32 i; - enum ir_protocol ir_protocol = - keyboard_layout_maps[coredev->ir.ir_kb_type] - .ir_protocol; - s32 *samples; - int count = len>>2; - - samples = (s32 *)buf; -/* sms_log("IR buffer received, length = %d", count);*/ - - for (i = 0; i < count; i++) - if (ir_protocol == IR_RC5) - sms_rc5_accumulate_bits(coredev, samples[i]); - /* IR_RCMM not implemented */ + ir_raw_event_handle(coredev->ir.input_dev); } int sms_ir_init(struct smscore_device_t *coredev) { struct input_dev *input_dev; + int board_id = smscore_get_board_id(coredev); sms_log("Allocating input device"); input_dev = input_allocate_device(); @@ -256,33 +63,38 @@ int sms_ir_init(struct smscore_device_t *coredev) } coredev->ir.input_dev = input_dev; - coredev->ir.ir_kb_type = - sms_get_board(smscore_get_board_id(coredev))->ir_kb_type; - coredev->ir.keyboard_layout_map = - keyboard_layout_maps[coredev->ir.ir_kb_type]. - keyboard_layout_map; - sms_log("IR remote keyboard type is %d", coredev->ir.ir_kb_type); coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ coredev->ir.timeout = IR_DEFAULT_TIMEOUT; sms_log("IR port %d, timeout %d ms", coredev->ir.controller, coredev->ir.timeout); - snprintf(coredev->ir.name, - IR_DEV_NAME_MAX_LEN, - "SMS IR w/kbd type %d", - coredev->ir.ir_kb_type); + snprintf(coredev->ir.name, sizeof(coredev->ir.name), + "SMS IR (%s)", sms_get_board(board_id)->name); + + strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys)); + strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys)); + input_dev->name = coredev->ir.name; - input_dev->phys = coredev->ir.name; + input_dev->phys = coredev->ir.phys; input_dev->dev.parent = coredev->device; - /* Key press events only */ - input_dev->evbit[0] = BIT_MASK(EV_KEY); - input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); +#if 0 + /* TODO: properly initialize the parameters bellow */ + input_dev->id.bustype = BUS_USB; + input_dev->id.version = 1; + input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); + input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); +#endif + + coredev->ir.props.priv = coredev; + coredev->ir.props.driver_type = RC_DRIVER_IR_RAW; + coredev->ir.props.allowed_protos = IR_TYPE_ALL; sms_log("Input device (IR) %s is set for key events", input_dev->name); - if (input_register_device(input_dev)) { + if (ir_input_register(input_dev, sms_get_board(board_id)->rc_codes, + &coredev->ir.props, MODULE_NAME)) { sms_err("Failed to register device"); input_free_device(input_dev); return -EACCES; @@ -294,8 +106,7 @@ int sms_ir_init(struct smscore_device_t *coredev) void sms_ir_exit(struct smscore_device_t *coredev) { if (coredev->ir.input_dev) - input_unregister_device(coredev->ir.input_dev); + ir_input_unregister(coredev->ir.input_dev); sms_log(""); } - diff --git a/drivers/media/dvb/siano/smsir.h b/drivers/media/dvb/siano/smsir.h index b7d703e2d33..926e247523b 100644 --- a/drivers/media/dvb/siano/smsir.h +++ b/drivers/media/dvb/siano/smsir.h @@ -4,6 +4,11 @@ Siano Mobile Silicon, Inc. MDTV receiver kernel modules. Copyright (C) 2006-2009, Uri Shkolnik + Copyright (c) 2010 - Mauro Carvalho Chehab + - Ported the driver to use rc-core + - IR raw event decoding is now done at rc-core + - Code almost re-written + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or @@ -23,63 +28,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define __SMS_IR_H__ #include <linux/input.h> +#include <media/ir-core.h> -#define IR_DEV_NAME_MAX_LEN 23 /* "SMS IR kbd type nn\0" */ -#define IR_KEYBOARD_LAYOUT_SIZE 64 #define IR_DEFAULT_TIMEOUT 100 -enum ir_kb_type { - SMS_IR_KB_DEFAULT_TV, - SMS_IR_KB_HCW_SILVER -}; - -enum rc5_keyboard_address { - KEYBOARD_ADDRESS_TV1 = 0, - KEYBOARD_ADDRESS_TV2 = 1, - KEYBOARD_ADDRESS_TELETEXT = 2, - KEYBOARD_ADDRESS_VIDEO = 3, - KEYBOARD_ADDRESS_LV1 = 4, - KEYBOARD_ADDRESS_VCR1 = 5, - KEYBOARD_ADDRESS_VCR2 = 6, - KEYBOARD_ADDRESS_EXPERIMENTAL = 7, - KEYBOARD_ADDRESS_SAT1 = 8, - KEYBOARD_ADDRESS_CAMERA = 9, - KEYBOARD_ADDRESS_SAT2 = 10, - KEYBOARD_ADDRESS_CDV = 12, - KEYBOARD_ADDRESS_CAMCORDER = 13, - KEYBOARD_ADDRESS_PRE_AMP = 16, - KEYBOARD_ADDRESS_TUNER = 17, - KEYBOARD_ADDRESS_RECORDER1 = 18, - KEYBOARD_ADDRESS_PRE_AMP1 = 19, - KEYBOARD_ADDRESS_CD_PLAYER = 20, - KEYBOARD_ADDRESS_PHONO = 21, - KEYBOARD_ADDRESS_SATA = 22, - KEYBOARD_ADDRESS_RECORDER2 = 23, - KEYBOARD_ADDRESS_CDR = 26, - KEYBOARD_ADDRESS_LIGHTING = 29, - KEYBOARD_ADDRESS_LIGHTING1 = 30, /* KEYBOARD_ADDRESS_HCW_SILVER */ - KEYBOARD_ADDRESS_PHONE = 31, - KEYBOARD_ADDRESS_NOT_RC5 = 0xFFFF -}; - -enum ir_protocol { - IR_RC5, - IR_RCMM -}; - -struct keyboard_layout_map_t { - enum ir_protocol ir_protocol; - enum rc5_keyboard_address rc5_kbd_address; - u16 keyboard_layout_map[IR_KEYBOARD_LAYOUT_SIZE]; -}; - struct smscore_device_t; struct ir_t { struct input_dev *input_dev; - enum ir_kb_type ir_kb_type; - char name[IR_DEV_NAME_MAX_LEN+1]; - u16 *keyboard_layout_map; + char name[40]; + char phys[32]; + + char *rc_codes; + u64 protocol; + struct ir_dev_props props; + u32 timeout; u32 controller; }; diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index a9c27fb69ba..50d4338610e 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -352,8 +352,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) params.num_buffers = MAX_BUFFERS; params.sendrequest_handler = smsusb_sendrequest; params.context = dev; - snprintf(params.devpath, sizeof(params.devpath), - "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath); + usb_make_path(dev->udev, params.devpath, sizeof(params.devpath)); /* register in smscore */ rc = smscore_register_device(¶ms, &dev->coredev); |