diff options
Diffstat (limited to 'drivers/media/usb/dvb-usb')
-rw-r--r-- | drivers/media/usb/dvb-usb/Kconfig | 3 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/cxusb.c | 233 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/cxusb.h | 2 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/dib0700_core.c | 45 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/dib0700_devices.c | 636 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/dibusb.h | 2 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/dvb-usb-remote.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/dw2102.c | 21 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/m920x.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/pctv452e.c | 8 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/technisat-usb2.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/ttusb2.c | 6 |
12 files changed, 678 insertions, 284 deletions
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig index c5d95662e2e1..10aef2188fbe 100644 --- a/drivers/media/usb/dvb-usb/Kconfig +++ b/drivers/media/usb/dvb-usb/Kconfig @@ -117,10 +117,12 @@ config DVB_USB_CXUSB select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT select DVB_ATBM8830 if MEDIA_SUBDRV_AUTOSELECT select DVB_LGS8GXX if MEDIA_SUBDRV_AUTOSELECT + select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_MAX2165 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT help Say Y here to support the Conexant USB2.0 hybrid reference design. Currently, only DVB and ATSC modes are supported, analog mode @@ -128,6 +130,7 @@ config DVB_USB_CXUSB Medion MD95700 hybrid USB2.0 device. DViCO FusionHDTV (Bluebird) USB2.0 devices + TechnoTrend TVStick CT2-4400 config DVB_USB_M920X tristate "Uli m920x DVB-T USB2.0 support" diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index a1c641e18362..16bc579d1404 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -42,9 +42,11 @@ #include "dib0070.h" #include "lgs8gxx.h" #include "atbm8830.h" +#include "si2168.h" +#include "si2157.h" /* Max transfer size done by I2C transfer functions */ -#define MAX_XFER_SIZE 64 +#define MAX_XFER_SIZE 80 /* debug */ static int dvb_usb_cxusb_debug; @@ -144,6 +146,22 @@ static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d, } } +static int cxusb_tt_ct2_4400_gpio_tuner(struct dvb_usb_device *d, int onoff) +{ + u8 o[2], i; + int rc; + + o[0] = 0x83; + o[1] = onoff; + rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); + + if (rc) { + deb_info("gpio_write failed.\n"); + return -EIO; + } + return 0; +} + /* I2C */ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) @@ -505,6 +523,30 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event, return 0; } +static int cxusb_tt_ct2_4400_rc_query(struct dvb_usb_device *d) +{ + u8 i[2]; + int ret; + u32 cmd, keycode; + u8 rc5_cmd, rc5_addr, rc5_toggle; + + ret = cxusb_ctrl_msg(d, 0x10, NULL, 0, i, 2); + if (ret) + return ret; + + cmd = (i[0] << 8) | i[1]; + + if (cmd != 0xffff) { + rc5_cmd = cmd & 0x3F; /* bits 1-6 for command */ + rc5_addr = (cmd & 0x07C0) >> 6; /* bits 7-11 for address */ + rc5_toggle = (cmd & 0x0800) >> 11; /* bit 12 for toggle */ + keycode = (rc5_addr << 8) | rc5_cmd; + rc_keydown(d->rc_dev, RC_BIT_RC5, keycode, rc5_toggle); + } + + return 0; +} + static struct rc_map_table rc_map_dvico_mce_table[] = { { 0xfe02, KEY_TV }, { 0xfe0e, KEY_MP3 }, @@ -1070,8 +1112,15 @@ static struct dib7000p_config cxusb_dualdig4_rev2_config = { .hostbus_diversity = 1, }; +struct dib0700_adapter_state { + int (*set_param_save)(struct dvb_frontend *); + struct dib7000p_ops dib7000p_ops; +}; + static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + if (usb_set_interface(adap->dev->udev, 0, 1) < 0) err("set interface failed"); @@ -1079,14 +1128,17 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - &cxusb_dualdig4_rev2_config) < 0) { + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + &cxusb_dualdig4_rev2_config) < 0) { printk(KERN_WARNING "Unable to enumerate dib7000p\n"); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, - &cxusb_dualdig4_rev2_config); + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, + &cxusb_dualdig4_rev2_config); if (adap->fe_adap[0].fe == NULL) return -EIO; @@ -1095,7 +1147,10 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) { - return dib7000p_set_gpio(fe, 8, 0, !onoff); + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + + return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff); } static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) @@ -1110,10 +1165,6 @@ static struct dib0070_config dib7070p_dib0070_config = { .clock_khz = 12000, }; -struct dib0700_adapter_state { - int (*set_param_save) (struct dvb_frontend *); -}; - static int dib7070_set_param_override(struct dvb_frontend *fe) { struct dtv_frontend_properties *p = &fe->dtv_property_cache; @@ -1128,7 +1179,7 @@ static int dib7070_set_param_override(struct dvb_frontend *fe) case BAND_UHF: offset = 550; break; } - dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); + state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); return state->set_param_save(fe); } @@ -1136,8 +1187,14 @@ static int dib7070_set_param_override(struct dvb_frontend *fe) static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = - dib7000p_get_i2c_master(adap->fe_adap[0].fe, + struct i2c_adapter *tun_i2c; + + /* + * No need to call dvb7000p_attach here, as it was called + * already, as frontend_attach method is called first, and + * tuner_attach is only called on sucess. + */ + tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, @@ -1286,6 +1343,74 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) return 0; } +static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap) +{ + struct dvb_usb_device *d = adap->dev; + struct cxusb_state *st = d->priv; + struct i2c_adapter *adapter; + struct i2c_client *client_demod; + struct i2c_client *client_tuner; + struct i2c_board_info info; + struct si2168_config si2168_config; + struct si2157_config si2157_config; + + /* reset the tuner */ + if (cxusb_tt_ct2_4400_gpio_tuner(d, 0) < 0) { + err("clear tuner gpio failed"); + return -EIO; + } + msleep(100); + if (cxusb_tt_ct2_4400_gpio_tuner(d, 1) < 0) { + err("set tuner gpio failed"); + return -EIO; + } + msleep(100); + + /* attach frontend */ + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &adap->fe_adap[0].fe; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + request_module(info.type); + client_demod = i2c_new_device(&d->i2c_adap, &info); + if (client_demod == NULL || client_demod->dev.driver == NULL) + return -ENODEV; + + if (!try_module_get(client_demod->dev.driver->owner)) { + i2c_unregister_device(client_demod); + return -ENODEV; + } + + st->i2c_client_demod = client_demod; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = adap->fe_adap[0].fe; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + request_module(info.type); + client_tuner = i2c_new_device(adapter, &info); + if (client_tuner == NULL || client_tuner->dev.driver == NULL) { + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + return -ENODEV; + } + if (!try_module_get(client_tuner->dev.driver->owner)) { + i2c_unregister_device(client_tuner); + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + return -ENODEV; + } + + st->i2c_client_tuner = client_tuner; + + return 0; +} + /* * DViCO has shipped two devices with the same USB ID, but only one of them * needs a firmware download. Check the device class details to see if they @@ -1367,6 +1492,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope static struct dvb_usb_device_properties cxusb_aver_a868r_properties; static struct dvb_usb_device_properties cxusb_d680_dmb_properties; static struct dvb_usb_device_properties cxusb_mygica_d689_properties; +static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties; static int cxusb_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -1397,12 +1523,37 @@ static int cxusb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_tt_ct2_4400_properties, + THIS_MODULE, NULL, adapter_nr) || 0) return 0; return -EINVAL; } +static void cxusb_disconnect(struct usb_interface *intf) +{ + struct dvb_usb_device *d = usb_get_intfdata(intf); + struct cxusb_state *st = d->priv; + struct i2c_client *client; + + /* remove I2C client for tuner */ + client = st->i2c_client_tuner; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + + /* remove I2C client for demodulator */ + client = st->i2c_client_demod; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + + dvb_usb_device_exit(intf); +} + static struct usb_device_id cxusb_table [] = { { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) }, @@ -1424,6 +1575,7 @@ static struct usb_device_id cxusb_table [] = { { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) }, { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) }, { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) }, + { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, cxusb_table); @@ -2070,10 +2222,63 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { } }; +static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + + .size_of_priv = sizeof(struct cxusb_state), + + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .streaming_ctrl = cxusb_streaming_ctrl, + /* both frontend and tuner attached in the + same function */ + .frontend_attach = cxusb_tt_ct2_4400_attach, + + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + } }, + }, + }, + + .i2c_algo = &cxusb_i2c_algo, + .generic_bulk_ctrl_endpoint = 0x01, + .generic_bulk_ctrl_endpoint_response = 0x81, + + .rc.core = { + .rc_codes = RC_MAP_TT_1500, + .allowed_protos = RC_BIT_RC5, + .rc_query = cxusb_tt_ct2_4400_rc_query, + .rc_interval = 150, + }, + + .num_device_descs = 1, + .devices = { + { + "TechnoTrend TVStick CT2-4400", + { NULL }, + { &cxusb_table[20], NULL }, + }, + } +}; + static struct usb_driver cxusb_driver = { .name = "dvb_usb_cxusb", .probe = cxusb_probe, - .disconnect = dvb_usb_device_exit, + .disconnect = cxusb_disconnect, .id_table = cxusb_table, }; diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h index 1a51eafd31b9..527ff7905e15 100644 --- a/drivers/media/usb/dvb-usb/cxusb.h +++ b/drivers/media/usb/dvb-usb/cxusb.h @@ -30,6 +30,8 @@ struct cxusb_state { u8 gpio_write_state[3]; + struct i2c_client *i2c_client_demod; + struct i2c_client *i2c_client_tuner; }; #endif diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c index c14285fa8271..50856dbf5496 100644 --- a/drivers/media/usb/dvb-usb/dib0700_core.c +++ b/drivers/media/usb/dvb-usb/dib0700_core.c @@ -658,13 +658,8 @@ out: struct dib0700_rc_response { u8 report_id; u8 data_state; - union { - u16 system16; - struct { - u8 not_system; - u8 system; - }; - }; + u8 system; + u8 not_system; u8 data; u8 not_data; }; @@ -674,6 +669,7 @@ static void dib0700_rc_urb_completion(struct urb *purb) { struct dvb_usb_device *d = purb->context; struct dib0700_rc_response *poll_reply; + enum rc_type protocol; u32 uninitialized_var(keycode); u8 toggle; @@ -707,44 +703,55 @@ static void dib0700_rc_urb_completion(struct urb *purb) switch (d->props.rc.core.protocol) { case RC_BIT_NEC: + protocol = RC_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)) { + if (poll_reply->system == 0x00 && + poll_reply->not_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) { + if ((poll_reply->data ^ poll_reply->not_data) != 0xff) { + deb_data("NEC32 protocol\n"); + keycode = RC_SCANCODE_NEC32(poll_reply->system << 24 | + poll_reply->not_system << 16 | + poll_reply->data << 8 | + poll_reply->not_data); + } else if ((poll_reply->system ^ poll_reply->not_system) != 0xff) { deb_data("NEC extended protocol\n"); - /* NEC extended code - 24 bits */ - keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data; + keycode = RC_SCANCODE_NECX(poll_reply->system << 8 | + poll_reply->not_system, + poll_reply->data); + } else { deb_data("NEC normal protocol\n"); - /* normal NEC code - 16 bits */ - keycode = poll_reply->system << 8 | poll_reply->data; + keycode = RC_SCANCODE_NEC(poll_reply->system, + poll_reply->data); } break; default: deb_data("RC5 protocol\n"); - /* RC5 Protocol */ + protocol = RC_TYPE_RC5; toggle = poll_reply->report_id; - keycode = poll_reply->system << 8 | poll_reply->data; + keycode = RC_SCANCODE_RC5(poll_reply->system, poll_reply->data); break; } if ((poll_reply->data + poll_reply->not_data) != 0xff) { /* Key failed integrity check */ - err("key failed integrity check: %04x %02x %02x", - poll_reply->system, + err("key failed integrity check: %02x %02x %02x %02x", + poll_reply->system, poll_reply->not_system, poll_reply->data, poll_reply->not_data); goto resubmit; } - rc_keydown(d->rc_dev, keycode, toggle); + rc_keydown(d->rc_dev, protocol, keycode, toggle); resubmit: /* Clean the buffer before we requeue */ diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 10e0db8d1850..ce47d3f1c850 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -32,6 +32,8 @@ MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplif struct dib0700_adapter_state { int (*set_param_save) (struct dvb_frontend *); const struct firmware *frontend_firmware; + struct dib7000p_ops dib7000p_ops; + struct dib8000_ops dib8000_ops; }; /* Hauppauge Nova-T 500 (aka Bristol) @@ -262,6 +264,11 @@ static struct mt2266_config stk7700d_mt2266_config[2] = { static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + if (adap->id == 0) { dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); @@ -272,16 +279,16 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, stk7700d_dib7000p_mt2266_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } } - adap->fe_adap[0].fe = - dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80 + (adap->id << 1), &stk7700d_dib7000p_mt2266_config[adap->id]); @@ -290,6 +297,11 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + if (adap->id == 0) { dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); @@ -301,16 +313,16 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7700d_dib7000p_mt2266_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } } - adap->fe_adap[0].fe = - dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80 + (adap->id << 1), &stk7700d_dib7000p_mt2266_config[adap->id]); @@ -320,7 +332,10 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *tun_i2c; - tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + struct dib0700_adapter_state *state = adap->priv; + + tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, + DIBX000_I2C_INTERFACE_TUNER, 1); return dvb_attach(mt2266_attach, adap->fe_adap[0].fe, tun_i2c, &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0; } @@ -397,12 +412,14 @@ static int stk7700ph_xc3028_callback(void *ptr, int component, int command, int arg) { struct dvb_usb_adapter *adap = ptr; + struct dib0700_adapter_state *state = adap->priv; switch (command) { case XC2028_TUNER_RESET: /* Send the tuner in then out of reset */ - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10); - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 0); + msleep(10); + state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); break; case XC2028_RESET_CLK: break; @@ -428,12 +445,16 @@ static struct xc2028_config stk7700ph_xc3028_config = { static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) { struct usb_device_descriptor *desc = &adap->dev->udev->descriptor; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) && desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX)) - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); else - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(20); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); @@ -445,14 +466,15 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); msleep(10); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &stk7700ph_dib7700_xc3028_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &stk7700ph_dib7700_xc3028_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -461,8 +483,9 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *tun_i2c; + struct dib0700_adapter_state *state = adap->priv; - tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, + tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); stk7700ph_xc3028_config.i2c_adap = tun_i2c; @@ -489,7 +512,8 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) { u8 key[4]; - u32 keycode; + enum rc_type protocol; + u32 scancode; u8 toggle; int i; struct dib0700_state *st = d->priv; @@ -516,28 +540,29 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) dib0700_rc_setup(d, NULL); /* reset ir sensor data to prevent false events */ - d->last_event = 0; switch (d->props.rc.core.protocol) { case RC_BIT_NEC: /* NEC protocol sends repeat code as 0 0 0 FF */ if ((key[3-2] == 0x00) && (key[3-3] == 0x00) && - (key[3] == 0xff)) - keycode = d->last_event; - else { - keycode = key[3-2] << 8 | key[3-3]; - d->last_event = keycode; + (key[3] == 0xff)) { + rc_repeat(d->rc_dev); + return 0; } - rc_keydown(d->rc_dev, keycode, 0); + protocol = RC_TYPE_NEC; + scancode = RC_SCANCODE_NEC(key[3-2], key[3-3]); + toggle = 0; break; + default: /* RC-5 protocol changes toggle bit on new keypress */ - keycode = key[3-2] << 8 | key[3-3]; + protocol = RC_TYPE_RC5; + scancode = RC_SCANCODE_RC5(key[3-2], key[3-3]); toggle = key[3-1]; - rc_keydown(d->rc_dev, keycode, toggle); - break; } + + rc_keydown(d->rc_dev, protocol, scancode, toggle); return 0; } @@ -673,6 +698,11 @@ static struct dib7000p_config stk7700p_dib7000p_config = { static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + /* unless there is no real power management in DVB - we leave the device on GPIO6 */ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); @@ -689,11 +719,13 @@ static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap) st->mt2060_if1[0] = 1220; - if (dib7000pc_detection(&adap->dev->i2c_adap)) { - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config); + if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap)) { + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config); st->is_dib7000pc = 1; - } else + } else { + memset(&state->dib7000p_ops, 0, sizeof(state->dib7000p_ops)); adap->fe_adap[0].fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config); + } return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -707,14 +739,16 @@ static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap) struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap; struct dib0700_state *st = adap->dev->priv; struct i2c_adapter *tun_i2c; + struct dib0700_adapter_state *state = adap->priv; s8 a; int if1=1220; + if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) && adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) { if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a; } if (st->is_dib7000pc) - tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); else tun_i2c = dib7000m_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); @@ -767,14 +801,20 @@ static struct dibx000_agc_config dib7070_agc_config = { static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) { + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + deb_info("reset: %d", onoff); - return dib7000p_set_gpio(fe, 8, 0, !onoff); + return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff); } static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) { + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + deb_info("sleep: %d", onoff); - return dib7000p_set_gpio(fe, 9, 0, onoff); + return state->dib7000p_ops.set_gpio(fe, 9, 0, onoff); } static struct dib0070_config dib7070p_dib0070_config[2] = { @@ -818,7 +858,7 @@ static int dib7070_set_param_override(struct dvb_frontend *fe) default: offset = 550; break; } deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); - dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); + state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); return state->set_param_save(fe); } @@ -832,39 +872,39 @@ static int dib7770_set_param_override(struct dvb_frontend *fe) u8 band = BAND_OF_FREQUENCY(p->frequency/1000); switch (band) { case BAND_VHF: - dib7000p_set_gpio(fe, 0, 0, 1); + state->dib7000p_ops.set_gpio(fe, 0, 0, 1); offset = 850; break; case BAND_UHF: default: - dib7000p_set_gpio(fe, 0, 0, 0); + state->dib7000p_ops.set_gpio(fe, 0, 0, 0); offset = 250; break; } deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); - dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); + state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); return state->set_param_save(fe); } static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap) { - struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); - if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, - &dib7770p_dib0070_config) == NULL) - return -ENODEV; + if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, + &dib7770p_dib0070_config) == NULL) + return -ENODEV; - st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; - adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override; - return 0; + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override; + return 0; } static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (adap->id == 0) { if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL) @@ -882,28 +922,33 @@ static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap) static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { + struct dib0700_adapter_state *state = adapter->priv; struct dib0700_state *st = adapter->dev->priv; + if (st->is_dib7000pc) - return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); + return state->dib7000p_ops.pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); return dib7000m_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); } static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { struct dib0700_state *st = adapter->dev->priv; + struct dib0700_adapter_state *state = adapter->priv; if (st->is_dib7000pc) - return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); + return state->dib7000p_ops.pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); return dib7000m_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); } static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { - return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); + struct dib0700_adapter_state *state = adapter->priv; + return state->dib7000p_ops.pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); } static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { - return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); + struct dib0700_adapter_state *state = adapter->priv; + return state->dib7000p_ops.pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); } static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { @@ -936,6 +981,11 @@ static struct dib7000p_config dib7070p_dib7000p_config = { static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) { struct usb_device_descriptor *p = &adap->dev->udev->descriptor; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) && p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E)) dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); @@ -954,14 +1004,15 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &dib7070p_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &dib7070p_dib7000p_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -988,6 +1039,11 @@ static struct dib7000p_config dib7770p_dib7000p_config = { static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap) { struct usb_device_descriptor *p = &adap->dev->udev->descriptor; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) && p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E)) dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); @@ -1006,14 +1062,15 @@ static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &dib7770p_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &dib7770p_dib7000p_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -1161,12 +1218,18 @@ static struct dib8000_config dib807x_dib8000_config[2] = { static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff) { - return dib8000_set_gpio(fe, 5, 0, !onoff); + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + + return state->dib8000_ops.set_gpio(fe, 5, 0, !onoff); } static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff) { - return dib8000_set_gpio(fe, 0, 0, onoff); + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + + return state->dib8000_ops.set_gpio(fe, 0, 0, onoff); } static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = { @@ -1223,7 +1286,7 @@ static int dib807x_set_param_override(struct dvb_frontend *fe) offset += 250; break; } deb_info("WBD for DiB8000: %d\n", offset); - dib8000_set_wbd_ref(fe, offset); + state->dib8000_ops.set_wbd_ref(fe, offset); return state->set_param_save(fe); } @@ -1231,7 +1294,7 @@ static int dib807x_set_param_override(struct dvb_frontend *fe) static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, + struct i2c_adapter *tun_i2c = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (adap->id == 0) { @@ -1252,18 +1315,27 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { - return dib8000_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); + struct dib0700_adapter_state *state = adapter->priv; + + return state->dib8000_ops.pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); } static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { - return dib8000_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); + struct dib0700_adapter_state *state = adapter->priv; + + return state->dib8000_ops.pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); } /* STK807x */ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); @@ -1279,10 +1351,10 @@ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -1291,6 +1363,11 @@ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) /* STK807xPVR */ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(30); dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); @@ -1309,9 +1386,9 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); /* initialize IC 0 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0); + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -1319,10 +1396,15 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; + /* initialize IC 1 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0); + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x82, &dib807x_dib8000_config[1]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -1331,104 +1413,121 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) /* STK8096GP */ static struct dibx000_agc_config dib8090_agc_config[2] = { { - BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, + .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), - 787, - 10, - - 0, - 118, - - 0, - 3530, - 1, - 5, + .inv_gain = 787, + .time_stabiliz = 10, - 65535, - 0, + .alpha_level = 0, + .thlock = 118, - 65535, - 0, + .wbd_inv = 0, + .wbd_ref = 3530, + .wbd_sel = 1, + .wbd_alpha = 5, - 0, - 32, - 114, - 143, - 144, - 114, - 227, - 116, - 117, + .agc1_max = 65535, + .agc1_min = 0, - 28, - 26, - 31, - 51, + .agc2_max = 65535, + .agc2_min = 0, - 0, + .agc1_pt1 = 0, + .agc1_pt2 = 32, + .agc1_pt3 = 114, + .agc1_slope1 = 143, + .agc1_slope2 = 144, + .agc2_pt1 = 114, + .agc2_pt2 = 227, + .agc2_slope1 = 116, + .agc2_slope2 = 117, + + .alpha_mant = 28, + .alpha_exp = 26, + .beta_mant = 31, + .beta_exp = 51, + + .perform_agc_softsplit = 0, }, { - BAND_CBAND, + .band_caps = BAND_CBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), - 787, - 10, + .inv_gain = 787, + .time_stabiliz = 10, - 0, - 118, + .alpha_level = 0, + .thlock = 118, - 0, - 3530, - 1, - 5, + .wbd_inv = 0, + .wbd_ref = 3530, + .wbd_sel = 1, + .wbd_alpha = 5, - 0, - 0, + .agc1_max = 0, + .agc1_min = 0, - 65535, - 0, - - 0, - 32, - 114, - 143, - 144, - 114, - 227, - 116, - 117, - - 28, - 26, - 31, - 51, + .agc2_max = 65535, + .agc2_min = 0, - 0, + .agc1_pt1 = 0, + .agc1_pt2 = 32, + .agc1_pt3 = 114, + .agc1_slope1 = 143, + .agc1_slope2 = 144, + .agc2_pt1 = 114, + .agc2_pt2 = 227, + .agc2_slope1 = 116, + .agc2_slope2 = 117, + + .alpha_mant = 28, + .alpha_exp = 26, + .beta_mant = 31, + .beta_exp = 51, + + .perform_agc_softsplit = 0, } }; static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { - 54000, 13500, - 1, 18, 3, 1, 0, - 0, 0, 1, 1, 2, - (3 << 14) | (1 << 12) | (599 << 0), - (0 << 25) | 0, - 20199727, - 12000000, + .internal = 54000, + .sampling = 13500, + + .pll_prediv = 1, + .pll_ratio = 18, + .pll_range = 3, + .pll_reset = 1, + .pll_bypass = 0, + + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 1, + .ADClkSrc = 1, + .modulo = 2, + + .sad_cfg = (3 << 14) | (1 << 12) | (599 << 0), + + .ifreq = (0 << 25) | 0, + .timf = 20199727, + + .xtal_hz = 12000000, }; static int dib8090_get_adc_power(struct dvb_frontend *fe) { - return dib8000_get_adc_power(fe, 1); + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + + return state->dib8000_ops.get_adc_power(fe, 1); } static void dib8090_agc_control(struct dvb_frontend *fe, u8 restart) @@ -1551,10 +1650,10 @@ static int dib8096_set_param_override(struct dvb_frontend *fe) default: deb_info("Warning : Rf frequency (%iHz) is not in the supported range, using VHF switch ", fe->dtv_property_cache.frequency); case BAND_VHF: - dib8000_set_gpio(fe, 3, 0, 1); + state->dib8000_ops.set_gpio(fe, 3, 0, 1); break; case BAND_UHF: - dib8000_set_gpio(fe, 3, 0, 0); + state->dib8000_ops.set_gpio(fe, 3, 0, 0); break; } @@ -1568,7 +1667,7 @@ static int dib8096_set_param_override(struct dvb_frontend *fe) } /** Update PLL if needed ratio **/ - dib8000_update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, 0); + state->dib8000_ops.update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, 0); /** Get optimize PLL ratio to remove spurious **/ pll_ratio = dib8090_compute_pll_parameters(fe); @@ -1582,14 +1681,14 @@ static int dib8096_set_param_override(struct dvb_frontend *fe) timf = 18179756; /** Update ratio **/ - dib8000_update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, pll_ratio); + state->dib8000_ops.update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, pll_ratio); - dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, timf); + state->dib8000_ops.ctrl_timf(fe, DEMOD_TIMF_SET, timf); if (band != BAND_CBAND) { /* dib0090_get_wbd_target is returning any possible temperature compensated wbd-target */ target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2; - dib8000_set_wbd_ref(fe, target); + state->dib8000_ops.set_wbd_ref(fe, target); } if (band == BAND_CBAND) { @@ -1601,18 +1700,18 @@ static int dib8096_set_param_override(struct dvb_frontend *fe) msleep(ret); tune_state = dib0090_get_tune_state(fe); if (tune_state == CT_AGC_STEP_0) - dib8000_set_gpio(fe, 6, 0, 1); + state->dib8000_ops.set_gpio(fe, 6, 0, 1); else if (tune_state == CT_AGC_STEP_1) { dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); if (rf_gain_limit < 2000) /* activate the external attenuator in case of very high input power */ - dib8000_set_gpio(fe, 6, 0, 0); + state->dib8000_ops.set_gpio(fe, 6, 0, 0); } } while (tune_state < CT_AGC_STOP); deb_info("switching to PWM AGC\n"); dib0090_pwm_gain_reset(fe); - dib8000_pwm_agc_reset(fe); - dib8000_set_tune_state(fe, CT_DEMOD_START); + state->dib8000_ops.pwm_agc_reset(fe); + state->dib8000_ops.set_tune_state(fe, CT_DEMOD_START); } else { /* for everything else than CBAND we are using standard AGC */ deb_info("not tuning in CBAND - standard AGC startup\n"); @@ -1625,7 +1724,7 @@ static int dib8096_set_param_override(struct dvb_frontend *fe) static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + struct i2c_adapter *tun_i2c = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL) return -ENODEV; @@ -1637,6 +1736,11 @@ static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); @@ -1652,9 +1756,9 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0); + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -1663,16 +1767,16 @@ static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; struct i2c_adapter *tun_i2c; - struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe_adap[0].fe, 1); + struct dvb_frontend *fe_slave = st->dib8000_ops.get_slave_frontend(adap->fe_adap[0].fe, 1); if (fe_slave) { - tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1); + tun_i2c = st->dib8000_ops.get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1); if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL) return -ENODEV; fe_slave->dvb = adap->fe_adap[0].fe->dvb; fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override; } - tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + tun_i2c = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL) return -ENODEV; @@ -1685,6 +1789,10 @@ static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap) static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) { struct dvb_frontend *fe_slave; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(20); @@ -1703,14 +1811,18 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0); + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); if (adap->fe_adap[0].fe == NULL) return -ENODEV; - fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]); - dib8000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave); + /* Needed to increment refcount */ + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; + + fe_slave = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]); + state->dib8000_ops.set_slave_frontend(adap->fe_adap[0].fe, fe_slave); return fe_slave == NULL ? -ENODEV : 0; } @@ -1845,7 +1957,7 @@ static struct dib0090_wbd_slope dib8096p_wbd_table[] = { { 0xFFFF, 0, 0, 0, 0, 0}, }; -static const struct dib0090_config tfe8096p_dib0090_config = { +static struct dib0090_config tfe8096p_dib0090_config = { .io.clock_khz = 12000, .io.pll_bypass = 0, .io.pll_range = 0, @@ -1853,8 +1965,6 @@ static const struct dib0090_config tfe8096p_dib0090_config = { .io.pll_loopdiv = 6, .io.adc_clock_ratio = 0, .io.pll_int_loop_filt = 0, - .reset = dib8096p_tuner_sleep, - .sleep = dib8096p_tuner_sleep, .freq_offset_khz_uhf = -143, .freq_offset_khz_vhf = -143, @@ -1871,8 +1981,6 @@ static const struct dib0090_config tfe8096p_dib0090_config = { .fref_clock_ratio = 1, - .wbd = dib8096p_wbd_table, - .ls_cfg_pad_drv = 0, .data_tx_drv = 0, .low_if = NULL, @@ -1983,15 +2091,15 @@ static int dib8096p_agc_startup(struct dvb_frontend *fe) /* dib0090_get_wbd_target is returning any possible temperature compensated wbd-target */ target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; - dib8000_set_wbd_ref(fe, target); + state->dib8000_ops.set_wbd_ref(fe, target); if (dib8096p_get_best_sampling(fe, &adc) == 0) { pll.pll_ratio = adc.pll_loopdiv; pll.pll_prediv = adc.pll_prediv; dib0700_set_i2c_speed(adap->dev, 200); - dib8000_update_pll(fe, &pll, fe->dtv_property_cache.bandwidth_hz / 1000, 0); - dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf); + state->dib8000_ops.update_pll(fe, &pll, fe->dtv_property_cache.bandwidth_hz / 1000, 0); + state->dib8000_ops.ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf); dib0700_set_i2c_speed(adap->dev, 1000); } return 0; @@ -2001,6 +2109,10 @@ static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; u32 fw_version; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL); if (fw_version >= 0x10200) @@ -2021,10 +2133,10 @@ static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap) msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1); + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, - &adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config); + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, + 0x80, &tfe8096p_dib8000_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -2032,13 +2144,17 @@ static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap) static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe); + struct i2c_adapter *tun_i2c = st->dib8000_ops.get_i2c_tuner(adap->fe_adap[0].fe); + + tfe8096p_dib0090_config.reset = st->dib8000_ops.tuner_sleep; + tfe8096p_dib0090_config.sleep = st->dib8000_ops.tuner_sleep; + tfe8096p_dib0090_config.wbd = dib8096p_wbd_table; if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe8096p_dib0090_config) == NULL) return -ENODEV; - dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + st->dib8000_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup; @@ -2479,14 +2595,14 @@ static int dib7090_agc_startup(struct dvb_frontend *fe) memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); dib0090_pwm_gain_reset(fe); target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; - dib7000p_set_wbd_ref(fe, target); + state->dib7000p_ops.set_wbd_ref(fe, target); if (dib7090p_get_best_sampling(fe, &adc) == 0) { pll.pll_ratio = adc.pll_loopdiv; pll.pll_prediv = adc.pll_prediv; - dib7000p_update_pll(fe, &pll); - dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf); + state->dib7000p_ops.update_pll(fe, &pll); + state->dib7000p_ops.ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf); } return 0; } @@ -2501,14 +2617,17 @@ static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) static int tfe7790p_update_lna(struct dvb_frontend *fe, u16 agc_global) { + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + deb_info("update LNA: agc global=%i", agc_global); if (agc_global < 25000) { - dib7000p_set_gpio(fe, 8, 0, 0); - dib7000p_set_agc1_min(fe, 0); + state->dib7000p_ops.set_gpio(fe, 8, 0, 0); + state->dib7000p_ops.set_agc1_min(fe, 0); } else { - dib7000p_set_gpio(fe, 8, 0, 1); - dib7000p_set_agc1_min(fe, 32768); + state->dib7000p_ops.set_gpio(fe, 8, 0, 1); + state->dib7000p_ops.set_agc1_min(fe, 32768); } return 0; @@ -2644,13 +2763,16 @@ static struct dib7000p_config nim7090_dib7000p_config = { static int tfe7090p_pvr_update_lna(struct dvb_frontend *fe, u16 agc_global) { + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + deb_info("TFE7090P-PVR update LNA: agc global=%i", agc_global); if (agc_global < 25000) { - dib7000p_set_gpio(fe, 5, 0, 0); - dib7000p_set_agc1_min(fe, 0); + state->dib7000p_ops.set_gpio(fe, 5, 0, 0); + state->dib7000p_ops.set_agc1_min(fe, 0); } else { - dib7000p_set_gpio(fe, 5, 0, 1); - dib7000p_set_agc1_min(fe, 32768); + state->dib7000p_ops.set_gpio(fe, 5, 0, 1); + state->dib7000p_ops.set_agc1_min(fe, 32768); } return 0; @@ -2714,7 +2836,7 @@ static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = { } }; -static const struct dib0090_config nim7090_dib0090_config = { +static struct dib0090_config nim7090_dib0090_config = { .io.clock_khz = 12000, .io.pll_bypass = 0, .io.pll_range = 0, @@ -2722,14 +2844,10 @@ static const struct dib0090_config nim7090_dib0090_config = { .io.pll_loopdiv = 6, .io.adc_clock_ratio = 0, .io.pll_int_loop_filt = 0, - .reset = dib7090_tuner_sleep, - .sleep = dib7090_tuner_sleep, .freq_offset_khz_uhf = 0, .freq_offset_khz_vhf = 0, - .get_adc_power = dib7090_get_adc_power, - .clkouttobamse = 1, .analog_output = 0, @@ -2776,7 +2894,7 @@ static struct dib7000p_config tfe7790p_dib7000p_config = { .enMpegOutput = 1, }; -static const struct dib0090_config tfe7790p_dib0090_config = { +static struct dib0090_config tfe7790p_dib0090_config = { .io.clock_khz = 12000, .io.pll_bypass = 0, .io.pll_range = 0, @@ -2784,14 +2902,10 @@ static const struct dib0090_config tfe7790p_dib0090_config = { .io.pll_loopdiv = 6, .io.adc_clock_ratio = 0, .io.pll_int_loop_filt = 0, - .reset = dib7090_tuner_sleep, - .sleep = dib7090_tuner_sleep, .freq_offset_khz_uhf = 0, .freq_offset_khz_vhf = 0, - .get_adc_power = dib7090_get_adc_power, - .clkouttobamse = 1, .analog_output = 0, @@ -2813,7 +2927,7 @@ static const struct dib0090_config tfe7790p_dib0090_config = { .force_crystal_mode = 1, }; -static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { +static struct dib0090_config tfe7090pvr_dib0090_config[2] = { { .io.clock_khz = 12000, .io.pll_bypass = 0, @@ -2822,14 +2936,10 @@ static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { .io.pll_loopdiv = 6, .io.adc_clock_ratio = 0, .io.pll_int_loop_filt = 0, - .reset = dib7090_tuner_sleep, - .sleep = dib7090_tuner_sleep, .freq_offset_khz_uhf = 50, .freq_offset_khz_vhf = 70, - .get_adc_power = dib7090_get_adc_power, - .clkouttobamse = 1, .analog_output = 0, @@ -2854,14 +2964,10 @@ static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { .io.pll_loopdiv = 6, .io.adc_clock_ratio = 0, .io.pll_int_loop_filt = 0, - .reset = dib7090_tuner_sleep, - .sleep = dib7090_tuner_sleep, .freq_offset_khz_uhf = -50, .freq_offset_khz_vhf = -70, - .get_adc_power = dib7090_get_adc_power, - .clkouttobamse = 1, .analog_output = 0, @@ -2883,6 +2989,11 @@ static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { static int nim7090_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(20); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); @@ -2895,11 +3006,12 @@ static int nim7090_frontend_attach(struct dvb_usb_adapter *adap) msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) { + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config); + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -2907,12 +3019,16 @@ static int nim7090_frontend_attach(struct dvb_usb_adapter *adap) static int nim7090_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe); + + nim7090_dib0090_config.reset = st->dib7000p_ops.tuner_sleep, + nim7090_dib0090_config.sleep = st->dib7000p_ops.tuner_sleep, + nim7090_dib0090_config.get_adc_power = st->dib7000p_ops.get_adc_power; if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &nim7090_dib0090_config) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; @@ -2922,6 +3038,10 @@ static int nim7090_tuner_attach(struct dvb_usb_adapter *adap) static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; /* The TFE7090 requires the dib0700 to not be in master mode */ st->disable_streaming_master_mode = 1; @@ -2939,17 +3059,18 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); /* initialize IC 0 */ - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) { + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } dib0700_set_i2c_speed(adap->dev, 340); - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); if (adap->fe_adap[0].fe == NULL) return -ENODEV; - dib7090_slave_reset(adap->fe_adap[0].fe); + state->dib7000p_ops.slave_reset(adap->fe_adap[0].fe); return 0; } @@ -2957,19 +3078,24 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *i2c; + struct dib0700_adapter_state *state = adap->priv; if (adap->dev->adapter[0].fe_adap[0].fe == NULL) { err("the master dib7090 has to be initialized first"); return -ENODEV; /* the master device has not been initialized */ } - i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1); - if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + + i2c = state->dib7000p_ops.get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1); + if (state->dib7000p_ops.i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) { + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]); + adap->fe_adap[0].fe = state->dib7000p_ops.init(i2c, 0x92, &tfe7090pvr_dib7000p_config[1]); dib0700_set_i2c_speed(adap->dev, 200); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -2978,12 +3104,16 @@ static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap) static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe); + + tfe7090pvr_dib0090_config[0].reset = st->dib7000p_ops.tuner_sleep; + tfe7090pvr_dib0090_config[0].sleep = st->dib7000p_ops.tuner_sleep; + tfe7090pvr_dib0090_config[0].get_adc_power = st->dib7000p_ops.get_adc_power; if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; @@ -2993,12 +3123,16 @@ static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap) static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe); + + tfe7090pvr_dib0090_config[1].reset = st->dib7000p_ops.tuner_sleep; + tfe7090pvr_dib0090_config[1].sleep = st->dib7000p_ops.tuner_sleep; + tfe7090pvr_dib0090_config[1].get_adc_power = st->dib7000p_ops.get_adc_power; if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; @@ -3008,6 +3142,10 @@ static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap) static int tfe7790p_frontend_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; /* The TFE7790P requires the dib0700 to not be in master mode */ st->disable_streaming_master_mode = 1; @@ -3024,13 +3162,14 @@ static int tfe7790p_frontend_attach(struct dvb_usb_adapter *adap) msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &tfe7790p_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &tfe7790p_dib7000p_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -3040,13 +3179,18 @@ static int tfe7790p_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; struct i2c_adapter *tun_i2c = - dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe); + + + tfe7790p_dib0090_config.reset = st->dib7000p_ops.tuner_sleep; + tfe7790p_dib0090_config.sleep = st->dib7000p_ops.tuner_sleep; + tfe7790p_dib0090_config.get_adc_power = st->dib7000p_ops.get_adc_power; if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7790p_dib0090_config) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; @@ -3103,25 +3247,36 @@ static void stk7070pd_init(struct dvb_usb_device *dev) static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + stk7070pd_init(adap->dev); msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]); + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap) { - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]); + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -3164,6 +3319,10 @@ static int novatd_frontend_attach(struct dvb_usb_adapter *adap) { struct dvb_usb_device *dev = adap->dev; struct dib0700_state *st = dev->priv; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; if (adap->id == 0) { stk7070pd_init(dev); @@ -3173,15 +3332,16 @@ static int novatd_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0); dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&dev->i2c_adap, 2, 18, + if (state->dib7000p_ops.i2c_enumeration(&dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&dev->i2c_adap, adap->id == 0 ? 0x80 : 0x82, &stk7070pd_dib7000p_config[adap->id]); @@ -3291,12 +3451,13 @@ static int dib0700_xc4000_tuner_callback(void *priv, int component, int command, int arg) { struct dvb_usb_adapter *adap = priv; + struct dib0700_adapter_state *state = adap->priv; if (command == XC4000_TUNER_RESET) { /* Reset the tuner */ - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); + state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10); - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); } else { err("xc4000: unknown tuner callback command: %d\n", command); return -EINVAL; @@ -3374,6 +3535,10 @@ static struct dib7000p_config pctv_340e_config = { static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; /* Power Supply on */ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); @@ -3397,12 +3562,13 @@ static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap) msleep(500); - if (dib7000pc_detection(&adap->dev->i2c_adap) == 0) { + if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap) == 0) { /* Demodulator not found for some reason? */ + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x12, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x12, &pctv_340e_config); st->is_dib7000pc = 1; @@ -3420,9 +3586,10 @@ static struct xc4000_config dib7000p_xc4000_tunerconfig = { static int xc4000_tuner_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *tun_i2c; + struct dib0700_adapter_state *state = adap->priv; /* The xc4000 is not on the main i2c bus */ - tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, + tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (tun_i2c == NULL) { printk(KERN_ERR "Could not reach tuner i2c bus\n"); @@ -3636,6 +3803,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, + .size_of_priv = sizeof(struct dib0700_adapter_state), }, }, diff --git a/drivers/media/usb/dvb-usb/dibusb.h b/drivers/media/usb/dvb-usb/dibusb.h index e47c321b3ffc..32ab1392313f 100644 --- a/drivers/media/usb/dvb-usb/dibusb.h +++ b/drivers/media/usb/dvb-usb/dibusb.h @@ -36,7 +36,7 @@ /* * i2c read - * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word + * bulk write: 0x02 ((7bit i2c_addr << 1) | 0x01) register_bytes length_word * bulk read: byte_buffer (length_word bytes) */ #define DIBUSB_REQ_I2C_READ 0x02 diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c index 4058aea9272f..7b5dae3077f6 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c @@ -272,7 +272,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) dev->driver_name = d->props.rc.core.module_name; dev->map_name = d->props.rc.core.rc_codes; dev->change_protocol = d->props.rc.core.change_protocol; - rc_set_allowed_protocols(dev, d->props.rc.core.allowed_protos); + dev->allowed_protocols = d->props.rc.core.allowed_protos; dev->driver_type = d->props.rc.core.driver_type; usb_to_input_id(d->udev, &dev->input_id); dev->input_name = "IR-receiver inside an USB DVB receiver"; diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index ae0f56a32e4d..2add8c507ec9 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -1109,6 +1109,7 @@ static struct ds3000_config su3000_ds3000_config = { static struct cxd2820r_config cxd2820r_config = { .i2c_address = 0x6c, /* (0xd8 >> 1) */ .ts_mode = 0x38, + .ts_clock_inv = 1, }; static struct tda18271_config tda18271_config = { @@ -1387,20 +1388,27 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d) static int t220_frontend_attach(struct dvb_usb_adapter *d) { - u8 obuf[3] = { 0xe, 0x80, 0 }; + u8 obuf[3] = { 0xe, 0x87, 0 }; u8 ibuf[] = { 0 }; if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) err("command 0x0e transfer failed."); obuf[0] = 0xe; - obuf[1] = 0x83; + obuf[1] = 0x86; + obuf[2] = 1; + + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) + err("command 0x0e transfer failed."); + + obuf[0] = 0xe; + obuf[1] = 0x80; obuf[2] = 0; if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) err("command 0x0e transfer failed."); - msleep(100); + msleep(50); obuf[0] = 0xe; obuf[1] = 0x80; @@ -1482,7 +1490,7 @@ static int dw2102_rc_query(struct dvb_usb_device *d) if (msg.buf[0] != 0xff) { deb_rc("%s: rc code: %x, %x\n", __func__, key[0], key[1]); - rc_keydown(d->rc_dev, key[0], 1); + rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, key[0], 0); } } @@ -1503,7 +1511,7 @@ static int prof_rc_query(struct dvb_usb_device *d) if (msg.buf[0] != 0xff) { deb_rc("%s: rc code: %x, %x\n", __func__, key[0], key[1]); - rc_keydown(d->rc_dev, key[0]^0xff, 1); + rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, key[0]^0xff, 0); } } @@ -1524,7 +1532,8 @@ static int su3000_rc_query(struct dvb_usb_device *d) if (msg.buf[0] != 0xff) { deb_rc("%s: rc code: %x, %x\n", __func__, key[0], key[1]); - rc_keydown(d->rc_dev, key[1] << 8 | key[0], 1); + rc_keydown(d->rc_dev, RC_TYPE_RC5, + RC_SCANCODE_RC5(key[1], key[0]), 0); } } diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c index 0306cb778df4..abf8ab2e02e5 100644 --- a/drivers/media/usb/dvb-usb/m920x.c +++ b/drivers/media/usb/dvb-usb/m920x.c @@ -245,7 +245,7 @@ static int m920x_rc_core_query(struct dvb_usb_device *d) else if (state == REMOTE_KEY_REPEAT) rc_repeat(d->rc_dev); else - rc_keydown(d->rc_dev, rc_state[1], 0); + rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, rc_state[1], 0); out: kfree(rc_state); diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c index 449a99605a87..bdfe8963591c 100644 --- a/drivers/media/usb/dvb-usb/pctv452e.c +++ b/drivers/media/usb/dvb-usb/pctv452e.c @@ -565,12 +565,12 @@ static int pctv452e_rc_query(struct dvb_usb_device *d) if ((rx[3] == 9) && (rx[12] & 0x01)) { /* got a "press" event */ - state->last_rc_key = (rx[7] << 8) | rx[6]; + state->last_rc_key = RC_SCANCODE_RC5(rx[7], rx[6]); if (debug > 2) info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[6], rx[7]); - rc_keydown(d->rc_dev, state->last_rc_key, 0); + rc_keydown(d->rc_dev, RC_TYPE_RC5, state->last_rc_key, 0); } else if (state->last_rc_key) { rc_keyup(d->rc_dev); state->last_rc_key = 0; @@ -927,7 +927,7 @@ static struct dvb_usb_device_properties pctv452e_properties = { .rc.core = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, - .allowed_protos = RC_BIT_UNKNOWN, + .allowed_protos = RC_BIT_RC5, .rc_query = pctv452e_rc_query, .rc_interval = 100, }, @@ -980,7 +980,7 @@ static struct dvb_usb_device_properties tt_connect_s2_3600_properties = { .rc.core = { .rc_codes = RC_MAP_TT_1500, - .allowed_protos = RC_BIT_UNKNOWN, + .allowed_protos = RC_BIT_RC5, .rc_query = pctv452e_rc_query, .rc_interval = 100, }, diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c index d947e0379008..6b0b8b6b9e2a 100644 --- a/drivers/media/usb/dvb-usb/technisat-usb2.c +++ b/drivers/media/usb/dvb-usb/technisat-usb2.c @@ -710,7 +710,7 @@ static struct dvb_usb_device_properties technisat_usb2_devices = { .isoc = { .framesperurb = 32, .framesize = 2048, - .interval = 3, + .interval = 1, } } }, diff --git a/drivers/media/usb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c index 2ce3d19c58ef..f10717311e05 100644 --- a/drivers/media/usb/dvb-usb/ttusb2.c +++ b/drivers/media/usb/dvb-usb/ttusb2.c @@ -438,9 +438,9 @@ static int tt3650_rc_query(struct dvb_usb_device *d) if (rx[8] & 0x01) { /* got a "press" event */ - st->last_rc_key = (rx[3] << 8) | rx[2]; + st->last_rc_key = RC_SCANCODE_RC5(rx[3], rx[2]); deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]); - rc_keydown(d->rc_dev, st->last_rc_key, rx[1]); + rc_keydown(d->rc_dev, RC_TYPE_RC5, st->last_rc_key, rx[1]); } else if (st->last_rc_key) { rc_keyup(d->rc_dev); st->last_rc_key = 0; @@ -747,7 +747,7 @@ static struct dvb_usb_device_properties ttusb2_properties_ct3650 = { .rc_interval = 150, /* Less than IR_KEYPRESS_TIMEOUT */ .rc_codes = RC_MAP_TT_1500, .rc_query = tt3650_rc_query, - .allowed_protos = RC_BIT_UNKNOWN, + .allowed_protos = RC_BIT_RC5, }, .num_adapters = 1, |