diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
28 files changed, 2132 insertions, 598 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 58257165761..9f203c6767a 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -311,6 +311,7 @@ config DVB_USB_ANYSEE select DVB_STV0900 if !DVB_FE_CUSTOMISE select DVB_STV6110 if !DVB_FE_CUSTOMISE select DVB_ISL6423 if !DVB_FE_CUSTOMISE + select DVB_CXD2820R if !DVB_FE_CUSTOMISE help Say Y here to support the Anysee E30, Anysee E30 Plus or Anysee E30 C Plus DVB USB2.0 receiver. @@ -340,7 +341,7 @@ config DVB_USB_AF9015 config DVB_USB_CE6230 tristate "Intel CE6230 DVB-T USB2.0 support" - depends on DVB_USB && EXPERIMENTAL + depends on DVB_USB select DVB_ZL10353 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE help @@ -354,7 +355,7 @@ config DVB_USB_FRIIO config DVB_USB_EC168 tristate "E3C EC168 DVB-T USB2.0 support" - depends on DVB_USB && EXPERIMENTAL + depends on DVB_USB select DVB_EC100 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE help diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c index 3263e9749d0..740f3f496f1 100644 --- a/drivers/media/dvb/dvb-usb/af9005-fe.c +++ b/drivers/media/dvb/dvb-usb/af9005-fe.c @@ -303,7 +303,7 @@ static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe, return -EINVAL; } - /* read constellation mode */ + /* read modulation mode */ ret = af9005_read_register_bits(state->d, xd_g_reg_tpsd_const, reg_tpsd_const_pos, reg_tpsd_const_len, @@ -321,7 +321,7 @@ static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe, bits = 6; break; default: - err("invalid constellation mode"); + err("invalid modulation mode"); return -EINVAL; } *pre_bit_count = super_frame_count * 68 * 4 * x * bits; @@ -533,13 +533,13 @@ static int af9005_fe_read_signal_strength(struct dvb_frontend *fe, static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr) { - /* the snr can be derived from the ber and the constellation + /* the snr can be derived from the ber and the modulation but I don't think this kind of complex calculations belong in the driver. I may be wrong.... */ return -ENOSYS; } -static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) +static int af9005_fe_program_cfoe(struct dvb_usb_device *d, u32 bw) { u8 temp0, temp1, temp2, temp3, buf[4]; int ret; @@ -551,7 +551,7 @@ static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) u32 NS_coeff2_8k; switch (bw) { - case BANDWIDTH_6_MHZ: + case 6000000: NS_coeff1_2048Nu = 0x2ADB6DC; NS_coeff1_8191Nu = 0xAB7313; NS_coeff1_8192Nu = 0xAB6DB7; @@ -560,7 +560,7 @@ static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) NS_coeff2_8k = 0x55B6DC; break; - case BANDWIDTH_7_MHZ: + case 7000000: NS_coeff1_2048Nu = 0x3200001; NS_coeff1_8191Nu = 0xC80640; NS_coeff1_8192Nu = 0xC80000; @@ -569,7 +569,7 @@ static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) NS_coeff2_8k = 0x640000; break; - case BANDWIDTH_8_MHZ: + case 8000000: NS_coeff1_2048Nu = 0x3924926; NS_coeff1_8191Nu = 0xE4996E; NS_coeff1_8192Nu = 0xE49249; @@ -773,17 +773,17 @@ static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) } -static int af9005_fe_select_bw(struct dvb_usb_device *d, fe_bandwidth_t bw) +static int af9005_fe_select_bw(struct dvb_usb_device *d, u32 bw) { u8 temp; switch (bw) { - case BANDWIDTH_6_MHZ: + case 6000000: temp = 0; break; - case BANDWIDTH_7_MHZ: + case 7000000: temp = 1; break; - case BANDWIDTH_8_MHZ: + case 8000000: temp = 2; break; default: @@ -930,10 +930,11 @@ static int af9005_fe_init(struct dvb_frontend *fe) /* init other parameters: program cfoe and select bandwidth */ deb_info("program cfoe\n"); - if ((ret = af9005_fe_program_cfoe(state->d, BANDWIDTH_6_MHZ))) + ret = af9005_fe_program_cfoe(state->d, 6000000); + if (ret) return ret; - /* set read-update bit for constellation */ - deb_info("set read-update bit for constellation\n"); + /* set read-update bit for modulation */ + deb_info("set read-update bit for modulation\n"); if ((ret = af9005_write_register_bits(state->d, xd_p_reg_feq_read_update, reg_feq_read_update_pos, @@ -943,8 +944,8 @@ static int af9005_fe_init(struct dvb_frontend *fe) /* sample code has a set MPEG TS code here but sniffing reveals that it doesn't do it */ - /* set read-update bit to 1 for DCA constellation */ - deb_info("set read-update bit 1 for DCA constellation\n"); + /* set read-update bit to 1 for DCA modulation */ + deb_info("set read-update bit 1 for DCA modulation\n"); if ((ret = af9005_write_register_bits(state->d, xd_p_reg_dca_read_update, reg_dca_read_update_pos, @@ -1099,15 +1100,15 @@ static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) return 0; } -static int af9005_fe_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int af9005_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct af9005_fe_state *state = fe->demodulator_priv; int ret; u8 temp, temp0, temp1, temp2; deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency, - fep->u.ofdm.bandwidth); + fep->bandwidth_hz); if (fe->ops.tuner_ops.release == NULL) { err("Tuner not attached"); return -ENODEV; @@ -1167,10 +1168,10 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, /* select bandwidth */ deb_info("select bandwidth"); - ret = af9005_fe_select_bw(state->d, fep->u.ofdm.bandwidth); + ret = af9005_fe_select_bw(state->d, fep->bandwidth_hz); if (ret) return ret; - ret = af9005_fe_program_cfoe(state->d, fep->u.ofdm.bandwidth); + ret = af9005_fe_program_cfoe(state->d, fep->bandwidth_hz); if (ret) return ret; @@ -1189,7 +1190,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, return ret; /* set tuner */ deb_info("set tuner\n"); - ret = fe->ops.tuner_ops.set_params(fe, fep); + ret = fe->ops.tuner_ops.set_params(fe); if (ret) return ret; @@ -1225,9 +1226,9 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, return 0; } -static int af9005_fe_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int af9005_fe_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct af9005_fe_state *state = fe->demodulator_priv; int ret; u8 temp; @@ -1239,19 +1240,19 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, &temp); if (ret) return ret; - deb_info("===== fe_get_frontend ==============\n"); + deb_info("===== fe_get_frontend_legacy = =============\n"); deb_info("CONSTELLATION "); switch (temp) { case 0: - fep->u.ofdm.constellation = QPSK; + fep->modulation = QPSK; deb_info("QPSK\n"); break; case 1: - fep->u.ofdm.constellation = QAM_16; + fep->modulation = QAM_16; deb_info("QAM_16\n"); break; case 2: - fep->u.ofdm.constellation = QAM_64; + fep->modulation = QAM_64; deb_info("QAM_64\n"); break; } @@ -1266,19 +1267,19 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("HIERARCHY "); switch (temp) { case 0: - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; + fep->hierarchy = HIERARCHY_NONE; deb_info("NONE\n"); break; case 1: - fep->u.ofdm.hierarchy_information = HIERARCHY_1; + fep->hierarchy = HIERARCHY_1; deb_info("1\n"); break; case 2: - fep->u.ofdm.hierarchy_information = HIERARCHY_2; + fep->hierarchy = HIERARCHY_2; deb_info("2\n"); break; case 3: - fep->u.ofdm.hierarchy_information = HIERARCHY_4; + fep->hierarchy = HIERARCHY_4; deb_info("4\n"); break; } @@ -1302,23 +1303,23 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("CODERATE HP "); switch (temp) { case 0: - fep->u.ofdm.code_rate_HP = FEC_1_2; + fep->code_rate_HP = FEC_1_2; deb_info("FEC_1_2\n"); break; case 1: - fep->u.ofdm.code_rate_HP = FEC_2_3; + fep->code_rate_HP = FEC_2_3; deb_info("FEC_2_3\n"); break; case 2: - fep->u.ofdm.code_rate_HP = FEC_3_4; + fep->code_rate_HP = FEC_3_4; deb_info("FEC_3_4\n"); break; case 3: - fep->u.ofdm.code_rate_HP = FEC_5_6; + fep->code_rate_HP = FEC_5_6; deb_info("FEC_5_6\n"); break; case 4: - fep->u.ofdm.code_rate_HP = FEC_7_8; + fep->code_rate_HP = FEC_7_8; deb_info("FEC_7_8\n"); break; } @@ -1333,23 +1334,23 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("CODERATE LP "); switch (temp) { case 0: - fep->u.ofdm.code_rate_LP = FEC_1_2; + fep->code_rate_LP = FEC_1_2; deb_info("FEC_1_2\n"); break; case 1: - fep->u.ofdm.code_rate_LP = FEC_2_3; + fep->code_rate_LP = FEC_2_3; deb_info("FEC_2_3\n"); break; case 2: - fep->u.ofdm.code_rate_LP = FEC_3_4; + fep->code_rate_LP = FEC_3_4; deb_info("FEC_3_4\n"); break; case 3: - fep->u.ofdm.code_rate_LP = FEC_5_6; + fep->code_rate_LP = FEC_5_6; deb_info("FEC_5_6\n"); break; case 4: - fep->u.ofdm.code_rate_LP = FEC_7_8; + fep->code_rate_LP = FEC_7_8; deb_info("FEC_7_8\n"); break; } @@ -1363,19 +1364,19 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("GUARD INTERVAL "); switch (temp) { case 0: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; + fep->guard_interval = GUARD_INTERVAL_1_32; deb_info("1_32\n"); break; case 1: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; + fep->guard_interval = GUARD_INTERVAL_1_16; deb_info("1_16\n"); break; case 2: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; + fep->guard_interval = GUARD_INTERVAL_1_8; deb_info("1_8\n"); break; case 3: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; + fep->guard_interval = GUARD_INTERVAL_1_4; deb_info("1_4\n"); break; } @@ -1390,11 +1391,11 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("TRANSMISSION MODE "); switch (temp) { case 0: - fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; + fep->transmission_mode = TRANSMISSION_MODE_2K; deb_info("2K\n"); break; case 1: - fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; + fep->transmission_mode = TRANSMISSION_MODE_8K; deb_info("8K\n"); break; } @@ -1406,15 +1407,15 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("BANDWIDTH "); switch (temp) { case 0: - fep->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; + fep->bandwidth_hz = 6000000; deb_info("6\n"); break; case 1: - fep->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; + fep->bandwidth_hz = 7000000; deb_info("7\n"); break; case 2: - fep->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; + fep->bandwidth_hz = 8000000; deb_info("8\n"); break; } @@ -1454,9 +1455,9 @@ struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) } static struct dvb_frontend_ops af9005_fe_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "AF9005 USB DVB-T", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 250000, diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c index bd51a764351..af176b6ce73 100644 --- a/drivers/media/dvb/dvb-usb/af9005.c +++ b/drivers/media/dvb/dvb-usb/af9005.c @@ -30,7 +30,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))." DVB_USB_DEBUG_STATUS); /* enable obnoxious led */ -int dvb_usb_af9005_led = 1; +bool dvb_usb_af9005_led = 1; module_param_named(led, dvb_usb_af9005_led, bool, 0644); MODULE_PARM_DESC(led, "enable led (default: 1)."); @@ -977,11 +977,20 @@ static int af9005_usb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr); } +enum af9005_usb_table_entry { + AFATECH_AF9005, + TERRATEC_AF9005, + ANSONIC_AF9005, +}; + static struct usb_device_id af9005_usb_table[] = { - {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9005)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE)}, - {USB_DEVICE(USB_VID_ANSONIC, USB_PID_ANSONIC_DVBT_USB)}, - {0}, + [AFATECH_AF9005] = {USB_DEVICE(USB_VID_AFATECH, + USB_PID_AFATECH_AF9005)}, + [TERRATEC_AF9005] = {USB_DEVICE(USB_VID_TERRATEC, + USB_PID_TERRATEC_CINERGY_T_USB_XE)}, + [ANSONIC_AF9005] = {USB_DEVICE(USB_VID_ANSONIC, + USB_PID_ANSONIC_DVBT_USB)}, + { } }; MODULE_DEVICE_TABLE(usb, af9005_usb_table); @@ -1041,15 +1050,15 @@ static struct dvb_usb_device_properties af9005_properties = { .num_device_descs = 3, .devices = { {.name = "Afatech DVB-T USB1.1 stick", - .cold_ids = {&af9005_usb_table[0], NULL}, + .cold_ids = {&af9005_usb_table[AFATECH_AF9005], NULL}, .warm_ids = {NULL}, }, {.name = "TerraTec Cinergy T USB XE", - .cold_ids = {&af9005_usb_table[1], NULL}, + .cold_ids = {&af9005_usb_table[TERRATEC_AF9005], NULL}, .warm_ids = {NULL}, }, {.name = "Ansonic DVB-T USB1.1 stick", - .cold_ids = {&af9005_usb_table[2], NULL}, + .cold_ids = {&af9005_usb_table[ANSONIC_AF9005], NULL}, .warm_ids = {NULL}, }, {NULL}, diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h index c71c77bd7f4..6a2bf3de845 100644 --- a/drivers/media/dvb/dvb-usb/af9005.h +++ b/drivers/media/dvb/dvb-usb/af9005.h @@ -35,7 +35,7 @@ extern int dvb_usb_af9005_debug; #define deb_i2c(args...) dprintk(dvb_usb_af9005_debug,0x10,args) #define deb_fw(args...) dprintk(dvb_usb_af9005_debug,0x20,args) -extern int dvb_usb_af9005_led; +extern bool dvb_usb_af9005_led; /* firmware */ #define FW_BULKOUT_SIZE 250 diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 56cbd3636c3..282a43d648d 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -50,14 +50,14 @@ static int af9015_properties_count = ARRAY_SIZE(af9015_properties); static struct af9013_config af9015_af9013_config[] = { { - .demod_address = AF9015_I2C_DEMOD, - .output_mode = AF9013_OUTPUT_MODE_USB, + .i2c_addr = AF9015_I2C_DEMOD, + .ts_mode = AF9013_TS_USB, .api_version = { 0, 1, 9, 0 }, .gpio[0] = AF9013_GPIO_HI, .gpio[3] = AF9013_GPIO_TUNER_ON, }, { - .output_mode = AF9013_OUTPUT_MODE_SERIAL, + .ts_mode = AF9013_TS_SERIAL, .api_version = { 0, 1, 9, 0 }, .gpio[0] = AF9013_GPIO_TUNER_ON, .gpio[1] = AF9013_GPIO_LO, @@ -216,8 +216,8 @@ static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, { struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val}; - if (addr == af9015_af9013_config[0].demod_address || - addr == af9015_af9013_config[1].demod_address) + if (addr == af9015_af9013_config[0].i2c_addr || + addr == af9015_af9013_config[1].i2c_addr) req.addr_len = 3; return af9015_ctrl_msg(d, &req); @@ -228,8 +228,8 @@ static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, { struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; - if (addr == af9015_af9013_config[0].demod_address || - addr == af9015_af9013_config[1].demod_address) + if (addr == af9015_af9013_config[0].i2c_addr || + addr == af9015_af9013_config[1].i2c_addr) req.addr_len = 3; return af9015_ctrl_msg(d, &req); @@ -271,8 +271,8 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. return -EAGAIN; while (i < num) { - if (msg[i].addr == af9015_af9013_config[0].demod_address || - msg[i].addr == af9015_af9013_config[1].demod_address) { + if (msg[i].addr == af9015_af9013_config[0].i2c_addr || + msg[i].addr == af9015_af9013_config[1].i2c_addr) { addr = msg[i].buf[0] << 8; addr += msg[i].buf[1]; mbox = msg[i].buf[2]; @@ -288,8 +288,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = -EOPNOTSUPP; goto error; } - if (msg[i].addr == - af9015_af9013_config[0].demod_address) + if (msg[i].addr == af9015_af9013_config[0].i2c_addr) req.cmd = READ_MEMORY; else req.cmd = READ_I2C; @@ -307,7 +306,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. goto error; } if (msg[i].addr == - af9015_af9013_config[0].demod_address) { + af9015_af9013_config[0].i2c_addr) { ret = -EINVAL; goto error; } @@ -325,8 +324,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = -EOPNOTSUPP; goto error; } - if (msg[i].addr == - af9015_af9013_config[0].demod_address) + if (msg[i].addr == af9015_af9013_config[0].i2c_addr) req.cmd = WRITE_MEMORY; else req.cmd = WRITE_I2C; @@ -508,7 +506,7 @@ static int af9015_copy_firmware(struct dvb_usb_device *d) msleep(100); ret = af9015_read_reg_i2c(d, - af9015_af9013_config[1].demod_address, 0x98be, &val); + af9015_af9013_config[1].i2c_addr, 0x98be, &val); if (ret) goto error; else @@ -536,7 +534,7 @@ static int af9015_copy_firmware(struct dvb_usb_device *d) goto error; /* request boot firmware */ - ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].demod_address, + ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].i2c_addr, 0xe205, 1); deb_info("%s: firmware boot cmd status:%d\n", __func__, ret); if (ret) @@ -547,7 +545,7 @@ static int af9015_copy_firmware(struct dvb_usb_device *d) /* check firmware status */ ret = af9015_read_reg_i2c(d, - af9015_af9013_config[1].demod_address, 0x98be, &val); + af9015_af9013_config[1].i2c_addr, 0x98be, &val); deb_info("%s: firmware status cmd status:%d fw status:%02x\n", __func__, ret, val); if (ret) @@ -840,7 +838,7 @@ static int af9015_read_config(struct usb_device *udev) if (ret) goto error; - deb_info("%s: IR mode:%d\n", __func__, val); + 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.core.rc_codes = NULL; @@ -854,7 +852,7 @@ static int af9015_read_config(struct usb_device *udev) if (ret) goto error; af9015_config.dual_mode = val; - deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode); + deb_info("%s: TS mode=%d\n", __func__, af9015_config.dual_mode); /* Set adapter0 buffer size according to USB port speed, adapter1 buffer size can be static because it is enabled only USB2.0 */ @@ -878,7 +876,7 @@ static int af9015_read_config(struct usb_device *udev) ret = af9015_rw_udev(udev, &req); if (ret) goto error; - af9015_af9013_config[1].demod_address = val; + af9015_af9013_config[1].i2c_addr = val; /* enable 2nd adapter */ for (i = 0; i < af9015_properties_count; i++) @@ -900,34 +898,38 @@ static int af9015_read_config(struct usb_device *udev) goto error; switch (val) { case 0: - af9015_af9013_config[i].adc_clock = 28800; + af9015_af9013_config[i].clock = 28800000; break; case 1: - af9015_af9013_config[i].adc_clock = 20480; + af9015_af9013_config[i].clock = 20480000; break; case 2: - af9015_af9013_config[i].adc_clock = 28000; + af9015_af9013_config[i].clock = 28000000; break; case 3: - af9015_af9013_config[i].adc_clock = 25000; + af9015_af9013_config[i].clock = 25000000; break; }; - deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i, - val, af9015_af9013_config[i].adc_clock); + deb_info("%s: [%d] xtal=%d set clock=%d\n", __func__, i, + val, af9015_af9013_config[i].clock); - /* tuner IF */ + /* IF frequency */ req.addr = AF9015_EEPROM_IF1H + offset; ret = af9015_rw_udev(udev, &req); if (ret) goto error; - af9015_af9013_config[i].tuner_if = val << 8; + + af9015_af9013_config[i].if_frequency = val << 8; + req.addr = AF9015_EEPROM_IF1L + offset; ret = af9015_rw_udev(udev, &req); if (ret) goto error; - af9015_af9013_config[i].tuner_if += val; - deb_info("%s: [%d] IF1:%d\n", __func__, i, - af9015_af9013_config[0].tuner_if); + + af9015_af9013_config[i].if_frequency += val; + af9015_af9013_config[i].if_frequency *= 1000; + deb_info("%s: [%d] IF frequency=%d\n", __func__, i, + af9015_af9013_config[0].if_frequency); /* MT2060 IF1 */ req.addr = AF9015_EEPROM_MT2060_IF1H + offset; @@ -940,7 +942,7 @@ static int af9015_read_config(struct usb_device *udev) if (ret) goto error; af9015_config.mt2060_if1[i] += val; - deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i, + deb_info("%s: [%d] MT2060 IF1=%d\n", __func__, i, af9015_config.mt2060_if1[i]); /* tuner */ @@ -957,30 +959,30 @@ static int af9015_read_config(struct usb_device *udev) case AF9013_TUNER_TDA18271: case AF9013_TUNER_QT1010A: case AF9013_TUNER_TDA18218: - af9015_af9013_config[i].rf_spec_inv = 1; + af9015_af9013_config[i].spec_inv = 1; break; case AF9013_TUNER_MXL5003D: case AF9013_TUNER_MXL5005D: case AF9013_TUNER_MXL5005R: case AF9013_TUNER_MXL5007T: - af9015_af9013_config[i].rf_spec_inv = 0; + af9015_af9013_config[i].spec_inv = 0; break; case AF9013_TUNER_MC44S803: af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; - af9015_af9013_config[i].rf_spec_inv = 1; + af9015_af9013_config[i].spec_inv = 1; break; default: - warn("tuner id:%d not supported, please report!", val); + warn("tuner id=%d not supported, please report!", val); return -ENODEV; }; af9015_af9013_config[i].tuner = val; - deb_info("%s: [%d] tuner id:%d\n", __func__, i, val); + deb_info("%s: [%d] tuner id=%d\n", __func__, i, val); } error: if (ret) - err("eeprom read failed:%d", ret); + err("eeprom read failed=%d", ret); /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM content :-( Override some wrong values here. Ditto for the @@ -998,7 +1000,7 @@ error: af9015_properties[i].num_adapters = 1; /* set correct IF */ - af9015_af9013_config[0].tuner_if = 4570; + af9015_af9013_config[0].if_frequency = 4570000; } return ret; @@ -1093,9 +1095,79 @@ error: return ret; } +/* override demod callbacks for resource locking */ +static int af9015_af9013_set_frontend(struct dvb_frontend *fe) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->set_frontend[adap->id](fe); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + +/* override demod callbacks for resource locking */ +static int af9015_af9013_read_status(struct dvb_frontend *fe, + fe_status_t *status) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->read_status[adap->id](fe, status); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + +/* override demod callbacks for resource locking */ +static int af9015_af9013_init(struct dvb_frontend *fe) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->init[adap->id](fe); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + +/* override demod callbacks for resource locking */ +static int af9015_af9013_sleep(struct dvb_frontend *fe) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->sleep[adap->id](fe); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) { int ret; + struct af9015_state *state = adap->dev->priv; if (adap->id == 1) { /* copy firmware to 2nd demodulator */ @@ -1116,6 +1188,32 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) adap->fe_adap[0].fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id], &adap->dev->i2c_adap); + /* + * AF9015 firmware does not like if it gets interrupted by I2C adapter + * request on some critical phases. During normal operation I2C adapter + * is used only 2nd demodulator and tuner on dual tuner devices. + * Override demodulator callbacks and use mutex for limit access to + * those "critical" paths to keep AF9015 happy. + * Note: we abuse unused usb_mutex here. + */ + if (adap->fe_adap[0].fe) { + state->set_frontend[adap->id] = + adap->fe_adap[0].fe->ops.set_frontend; + adap->fe_adap[0].fe->ops.set_frontend = + af9015_af9013_set_frontend; + + state->read_status[adap->id] = + adap->fe_adap[0].fe->ops.read_status; + adap->fe_adap[0].fe->ops.read_status = + af9015_af9013_read_status; + + state->init[adap->id] = adap->fe_adap[0].fe->ops.init; + adap->fe_adap[0].fe->ops.init = af9015_af9013_init; + + state->sleep[adap->id] = adap->fe_adap[0].fe->ops.sleep; + adap->fe_adap[0].fe->ops.sleep = af9015_af9013_sleep; + } + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -1245,49 +1343,112 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) return ret; } +enum af9015_usb_table_entry { + AFATECH_9015, + AFATECH_9016, + WINFAST_DTV_GOLD, + PINNACLE_PCTV_71E, + KWORLD_PLUSTV_399U, + TINYTWIN, + AZUREWAVE_TU700, + TERRATEC_AF9015, + KWORLD_PLUSTV_PC160, + AVERTV_VOLAR_X, + XTENSIONS_380U, + MSI_DIGIVOX_DUO, + AVERTV_VOLAR_X_REV2, + TELESTAR_STARSTICK_2, + AVERMEDIA_A309_USB, + MSI_DIGIVOX_MINI_III, + KWORLD_E396, + KWORLD_E39B, + KWORLD_E395, + TREKSTOR_DVBT, + AVERTV_A850, + AVERTV_A805, + CONCEPTRONIC_CTVDIGRCU, + KWORLD_MC810, + GENIUS_TVGO_DVB_T03, + KWORLD_399U_2, + KWORLD_PC160_T, + SVEON_STV20, + TINYTWIN_2, + WINFAST_DTV2000DS, + KWORLD_UB383_T, + KWORLD_E39A, + AVERMEDIA_A815M, + CINERGY_T_STICK_RC, + CINERGY_T_DUAL_RC, + AVERTV_A850T, + TINYTWIN_3, + SVEON_STV22, +}; + static struct usb_device_id af9015_usb_table[] = { -/* 0 */{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)}, - {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)}, - {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)}, - {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)}, -/* 5 */{USB_DEVICE(USB_VID_VISIONPLUS, - USB_PID_TINYTWIN)}, - {USB_DEVICE(USB_VID_VISIONPLUS, - USB_PID_AZUREWAVE_AD_TU700)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)}, -/* 10 */{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)}, - {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)}, - {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)}, -/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)}, - {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)}, -/* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, - {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, -/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)}, - {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)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)}, - {USB_DEVICE(USB_VID_TERRATEC, - USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)}, -/* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)}, - {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)}, - {0}, + [AFATECH_9015] = + {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)}, + [AFATECH_9016] = + {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)}, + [WINFAST_DTV_GOLD] = + {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)}, + [PINNACLE_PCTV_71E] = + {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)}, + [KWORLD_PLUSTV_399U] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)}, + [TINYTWIN] = {USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN)}, + [AZUREWAVE_TU700] = + {USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700)}, + [TERRATEC_AF9015] = {USB_DEVICE(USB_VID_TERRATEC, + USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)}, + [KWORLD_PLUSTV_PC160] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)}, + [AVERTV_VOLAR_X] = + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)}, + [XTENSIONS_380U] = + {USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)}, + [MSI_DIGIVOX_DUO] = + {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)}, + [AVERTV_VOLAR_X_REV2] = + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)}, + [TELESTAR_STARSTICK_2] = + {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)}, + [AVERMEDIA_A309_USB] = + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)}, + [MSI_DIGIVOX_MINI_III] = + {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)}, + [KWORLD_E396] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)}, + [KWORLD_E39B] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, + [KWORLD_E395] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)}, + [TREKSTOR_DVBT] = {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)}, + [AVERTV_A850] = {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, + [AVERTV_A805] = {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)}, + [CONCEPTRONIC_CTVDIGRCU] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)}, + [KWORLD_MC810] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, + [GENIUS_TVGO_DVB_T03] = + {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, + [KWORLD_399U_2] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, + [KWORLD_PC160_T] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)}, + [SVEON_STV20] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)}, + [TINYTWIN_2] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)}, + [WINFAST_DTV2000DS] = + {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)}, + [KWORLD_UB383_T] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, + [KWORLD_E39A] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, + [AVERMEDIA_A815M] = + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, + [CINERGY_T_STICK_RC] = {USB_DEVICE(USB_VID_TERRATEC, + USB_PID_TERRATEC_CINERGY_T_STICK_RC)}, + [CINERGY_T_DUAL_RC] = {USB_DEVICE(USB_VID_TERRATEC, + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)}, + [AVERTV_A850T] = + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)}, + [TINYTWIN_3] = {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)}, + [SVEON_STV22] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)}, + { } }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1362,68 +1523,104 @@ static struct dvb_usb_device_properties af9015_properties[] = { .devices = { { .name = "Afatech AF9015 DVB-T USB2.0 stick", - .cold_ids = {&af9015_usb_table[0], - &af9015_usb_table[1], NULL}, + .cold_ids = { + &af9015_usb_table[AFATECH_9015], + &af9015_usb_table[AFATECH_9016], + NULL + }, .warm_ids = {NULL}, }, { .name = "Leadtek WinFast DTV Dongle Gold", - .cold_ids = {&af9015_usb_table[2], NULL}, + .cold_ids = { + &af9015_usb_table[WINFAST_DTV_GOLD], + NULL + }, .warm_ids = {NULL}, }, { .name = "Pinnacle PCTV 71e", - .cold_ids = {&af9015_usb_table[3], NULL}, + .cold_ids = { + &af9015_usb_table[PINNACLE_PCTV_71E], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld PlusTV Dual DVB-T Stick " \ "(DVB-T 399U)", - .cold_ids = {&af9015_usb_table[4], - &af9015_usb_table[25], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_PLUSTV_399U], + &af9015_usb_table[KWORLD_399U_2], + NULL + }, .warm_ids = {NULL}, }, { .name = "DigitalNow TinyTwin DVB-T Receiver", - .cold_ids = {&af9015_usb_table[5], - &af9015_usb_table[28], - &af9015_usb_table[36], NULL}, + .cold_ids = { + &af9015_usb_table[TINYTWIN], + &af9015_usb_table[TINYTWIN_2], + &af9015_usb_table[TINYTWIN_3], + NULL + }, .warm_ids = {NULL}, }, { .name = "TwinHan AzureWave AD-TU700(704J)", - .cold_ids = {&af9015_usb_table[6], NULL}, + .cold_ids = { + &af9015_usb_table[AZUREWAVE_TU700], + NULL + }, .warm_ids = {NULL}, }, { .name = "TerraTec Cinergy T USB XE", - .cold_ids = {&af9015_usb_table[7], NULL}, + .cold_ids = { + &af9015_usb_table[TERRATEC_AF9015], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld PlusTV Dual DVB-T PCI " \ "(DVB-T PC160-2T)", - .cold_ids = {&af9015_usb_table[8], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_PLUSTV_PC160], + NULL + }, .warm_ids = {NULL}, }, { .name = "AVerMedia AVerTV DVB-T Volar X", - .cold_ids = {&af9015_usb_table[9], NULL}, + .cold_ids = { + &af9015_usb_table[AVERTV_VOLAR_X], + NULL + }, .warm_ids = {NULL}, }, { .name = "TerraTec Cinergy T Stick RC", - .cold_ids = {&af9015_usb_table[33], NULL}, + .cold_ids = { + &af9015_usb_table[CINERGY_T_STICK_RC], + NULL + }, .warm_ids = {NULL}, }, { .name = "TerraTec Cinergy T Stick Dual RC", - .cold_ids = {&af9015_usb_table[34], NULL}, + .cold_ids = { + &af9015_usb_table[CINERGY_T_DUAL_RC], + NULL + }, .warm_ids = {NULL}, }, { .name = "AverMedia AVerTV Red HD+ (A850T)", - .cold_ids = {&af9015_usb_table[35], NULL}, + .cold_ids = { + &af9015_usb_table[AVERTV_A850T], + NULL + }, .warm_ids = {NULL}, }, } @@ -1496,57 +1693,87 @@ static struct dvb_usb_device_properties af9015_properties[] = { .devices = { { .name = "Xtensions XD-380", - .cold_ids = {&af9015_usb_table[10], NULL}, + .cold_ids = { + &af9015_usb_table[XTENSIONS_380U], + NULL + }, .warm_ids = {NULL}, }, { .name = "MSI DIGIVOX Duo", - .cold_ids = {&af9015_usb_table[11], NULL}, + .cold_ids = { + &af9015_usb_table[MSI_DIGIVOX_DUO], + NULL + }, .warm_ids = {NULL}, }, { .name = "Fujitsu-Siemens Slim Mobile USB DVB-T", - .cold_ids = {&af9015_usb_table[12], NULL}, + .cold_ids = { + &af9015_usb_table[AVERTV_VOLAR_X_REV2], + NULL + }, .warm_ids = {NULL}, }, { .name = "Telestar Starstick 2", - .cold_ids = {&af9015_usb_table[13], NULL}, + .cold_ids = { + &af9015_usb_table[TELESTAR_STARSTICK_2], + NULL + }, .warm_ids = {NULL}, }, { .name = "AVerMedia A309", - .cold_ids = {&af9015_usb_table[14], NULL}, + .cold_ids = { + &af9015_usb_table[AVERMEDIA_A309_USB], + NULL + }, .warm_ids = {NULL}, }, { .name = "MSI Digi VOX mini III", - .cold_ids = {&af9015_usb_table[15], NULL}, + .cold_ids = { + &af9015_usb_table[MSI_DIGIVOX_MINI_III], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld USB DVB-T TV Stick II " \ "(VS-DVB-T 395U)", - .cold_ids = {&af9015_usb_table[16], - &af9015_usb_table[17], - &af9015_usb_table[18], - &af9015_usb_table[31], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_E396], + &af9015_usb_table[KWORLD_E39B], + &af9015_usb_table[KWORLD_E395], + &af9015_usb_table[KWORLD_E39A], + NULL + }, .warm_ids = {NULL}, }, { .name = "TrekStor DVB-T USB Stick", - .cold_ids = {&af9015_usb_table[19], NULL}, + .cold_ids = { + &af9015_usb_table[TREKSTOR_DVBT], + NULL + }, .warm_ids = {NULL}, }, { .name = "AverMedia AVerTV Volar Black HD " \ "(A850)", - .cold_ids = {&af9015_usb_table[20], NULL}, + .cold_ids = { + &af9015_usb_table[AVERTV_A850], + NULL + }, .warm_ids = {NULL}, }, { .name = "Sveon STV22 Dual USB DVB-T Tuner HDTV", - .cold_ids = {&af9015_usb_table[37], NULL}, + .cold_ids = { + &af9015_usb_table[SVEON_STV22], + NULL + }, .warm_ids = {NULL}, }, } @@ -1619,50 +1846,77 @@ static struct dvb_usb_device_properties af9015_properties[] = { .devices = { { .name = "AverMedia AVerTV Volar GPS 805 (A805)", - .cold_ids = {&af9015_usb_table[21], NULL}, + .cold_ids = { + &af9015_usb_table[AVERTV_A805], + NULL + }, .warm_ids = {NULL}, }, { .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \ "V3.0", - .cold_ids = {&af9015_usb_table[22], NULL}, + .cold_ids = { + &af9015_usb_table[CONCEPTRONIC_CTVDIGRCU], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld Digial MC-810", - .cold_ids = {&af9015_usb_table[23], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_MC810], + NULL + }, .warm_ids = {NULL}, }, { .name = "Genius TVGo DVB-T03", - .cold_ids = {&af9015_usb_table[24], NULL}, + .cold_ids = { + &af9015_usb_table[GENIUS_TVGO_DVB_T03], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld PlusTV DVB-T PCI Pro Card " \ "(DVB-T PC160-T)", - .cold_ids = {&af9015_usb_table[26], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_PC160_T], + NULL + }, .warm_ids = {NULL}, }, { .name = "Sveon STV20 Tuner USB DVB-T HDTV", - .cold_ids = {&af9015_usb_table[27], NULL}, + .cold_ids = { + &af9015_usb_table[SVEON_STV20], + NULL + }, .warm_ids = {NULL}, }, { .name = "Leadtek WinFast DTV2000DS", - .cold_ids = {&af9015_usb_table[29], NULL}, + .cold_ids = { + &af9015_usb_table[WINFAST_DTV2000DS], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld USB DVB-T Stick Mobile " \ "(UB383-T)", - .cold_ids = {&af9015_usb_table[30], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_UB383_T], + NULL + }, .warm_ids = {NULL}, }, { .name = "AverMedia AVerTV Volar M (A815Mac)", - .cold_ids = {&af9015_usb_table[32], NULL}, + .cold_ids = { + &af9015_usb_table[AVERMEDIA_A815M], + NULL + }, .warm_ids = {NULL}, }, } diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index 6252ea6c190..f619063fa72 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -102,6 +102,12 @@ struct af9015_state { u8 rc_repeat; u32 rc_keycode; u8 rc_last[4]; + + /* for demod callback override */ + int (*set_frontend[2]) (struct dvb_frontend *fe); + int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status); + int (*init[2]) (struct dvb_frontend *fe); + int (*sleep[2]) (struct dvb_frontend *fe); }; struct af9015_config { diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index b39f14f85e7..1455e2644ab 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -41,6 +41,7 @@ #include "stv0900.h" #include "stv6110.h" #include "isl6423.h" +#include "cxd2820r.h" /* debug */ static int dvb_usb_anysee_debug; @@ -66,10 +67,12 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, if (mutex_lock_interruptible(&anysee_usb_mutex) < 0) return -EAGAIN; + deb_xfer(">>> "); + debug_dump(buf, slen, deb_xfer); + /* We need receive one message more after dvb_usb_generic_rw due to weird transaction flow, which is 1 x send + 2 x receive. */ ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); - if (!ret) { /* receive 2nd answer */ ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, @@ -79,7 +82,10 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, err("%s: recv bulk message failed: %d", __func__, ret); else { deb_xfer("<<< "); - debug_dump(buf, act_len, deb_xfer); + debug_dump(buf, rlen, deb_xfer); + + if (buf[63] != 0x4f) + deb_info("%s: cmd failed\n", __func__); } } @@ -129,6 +135,29 @@ static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val, return anysee_write_reg(d, reg, val); } +/* read single register with mask */ +static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val, + u8 mask) +{ + int ret, i; + u8 tmp; + + ret = anysee_read_reg(d, reg, &tmp); + if (ret) + return ret; + + tmp &= mask; + + /* find position of the first bit */ + for (i = 0; i < 8; i++) { + if ((mask >> i) & 0x01) + break; + } + *val = tmp >> i; + + return 0; +} + static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) { u8 buf[] = {CMD_GET_HW_INFO}; @@ -156,22 +185,6 @@ static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff) return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); } -static int anysee_init(struct dvb_usb_device *d) -{ - int ret; - /* LED light */ - ret = anysee_led_ctrl(d, 0x01, 0x03); - if (ret) - return ret; - - /* enable IR */ - ret = anysee_ir_ctrl(d, 1); - if (ret) - return ret; - - return 0; -} - /* I2C */ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) @@ -297,7 +310,7 @@ static struct tda10023_config anysee_tda10023_tda18212_config = { .pll_m = 12, .pll_p = 3, .pll_n = 1, - .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C, + .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B, .deltaf = 0xba02, }; @@ -309,6 +322,17 @@ static struct tda18212_config anysee_tda18212_config = { .if_dvbc = 5000, }; +static struct tda18212_config anysee_tda18212_config2 = { + .i2c_address = 0x60 /* (0xc0 >> 1) */, + .if_dvbt_6 = 3550, + .if_dvbt_7 = 3700, + .if_dvbt_8 = 4150, + .if_dvbt2_6 = 3250, + .if_dvbt2_7 = 4000, + .if_dvbt2_8 = 4000, + .if_dvbc = 5000, +}; + static struct cx24116_config anysee_cx24116_config = { .demod_address = (0xaa >> 1), .mpg_clk_pos_pol = 0x00, @@ -339,6 +363,11 @@ static struct isl6423_config anysee_isl6423_config = { .addr = (0x10 >> 1), }; +static struct cxd2820r_config anysee_cxd2820r_config = { + .i2c_address = 0x6d, /* (0xda >> 1) */ + .ts_mode = 0x38, +}; + /* * New USB device strings: Mfr=1, Product=2, SerialNumber=0 * Manufacturer: AMT.CO.KR @@ -421,6 +450,14 @@ static struct isl6423_config anysee_isl6423_config = { * IOA[7] TS 1=enabled * IOE[5] STV0903 1=enabled * + * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)" + * PCB: 508T2C (rev0.3) + * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024 + * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff + * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4 + * IOA[7] TS 1=enabled + * IOE[5] CXD2820R 1=enabled + * * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)" * PCB: 508PTC (rev0.5) * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212) @@ -437,7 +474,7 @@ static struct isl6423_config anysee_isl6423_config = { * IOD[6] ZL10353 1=enabled * IOE[0] IF 0=enabled * - * E7 S2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" + * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" * PCB: 508PS2 (rev0.4) * parts: DNBU10512IST(STV0903, STV6110), ISL6423 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff @@ -446,6 +483,16 @@ static struct isl6423_config anysee_isl6423_config = { * IOE[5] STV0903 1=enabled */ + +/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */ +static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + + /* enable / disable tuner access on IOE[4] */ + return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10); +} + static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff) { struct dvb_usb_adapter *adap = fe->dvb->priv; @@ -577,7 +624,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) /* detect hardware only once */ if (adap->fe_adap[0].fe == NULL) { /* Check which hardware we have. - * We must do this call two times to get reliable values (hw bug). + * We must do this call two times to get reliable values + * (hw/fw bug). */ ret = anysee_get_hw_info(adap->dev, hw_info); if (ret) @@ -606,14 +654,14 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) break; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(mt352_attach, &anysee_mt352_config, - &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(mt352_attach, + &anysee_mt352_config, &adap->dev->i2c_adap); if (adap->fe_adap[0].fe) break; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, - &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, + &anysee_zl10353_config, &adap->dev->i2c_adap); break; case ANYSEE_HW_507CD: /* 6 */ @@ -665,8 +713,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(cx24116_attach, &anysee_cx24116_config, - &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(cx24116_attach, + &anysee_cx24116_config, &adap->dev->i2c_adap); break; case ANYSEE_HW_507FA: /* 15 */ @@ -747,17 +795,19 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) } } + /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */ + if (tmp == 0xc7) { + if (adap->fe_adap[state->fe_id].fe) + adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = + anysee_i2c_gate_ctrl; + } + break; case ANYSEE_HW_508TC: /* 18 */ case ANYSEE_HW_508PTC: /* 21 */ /* E7 TC */ /* E7 PTC */ - /* enable transport stream on IOA[7] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); - if (ret) - goto error; - if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { /* disable DVB-T demod on IOD[6] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), @@ -772,7 +822,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe_adap[state->fe_id].fe = dvb_attach(tda10023_attach, + adap->fe_adap[state->fe_id].fe = + dvb_attach(tda10023_attach, &anysee_tda10023_tda18212_config, &adap->dev->i2c_adap, 0x48); } else { @@ -789,11 +840,19 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe_adap[state->fe_id].fe = dvb_attach(zl10353_attach, + adap->fe_adap[state->fe_id].fe = + dvb_attach(zl10353_attach, &anysee_zl10353_tda18212_config, &adap->dev->i2c_adap); } + /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */ + if (adap->fe_adap[state->fe_id].fe) + adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = + anysee_i2c_gate_ctrl; + + state->has_ci = true; + break; case ANYSEE_HW_508S2: /* 19 */ case ANYSEE_HW_508PS2: /* 22 */ @@ -803,19 +862,35 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) if (state->fe_id) break; - /* enable transport stream on IOA[7] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); + /* enable DVB-S/S2 demod on IOE[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); if (ret) goto error; - /* enable DVB-S/S2 demod on IOE[5] */ + /* attach demod */ + adap->fe_adap[0].fe = dvb_attach(stv0900_attach, + &anysee_stv0900_config, &adap->dev->i2c_adap, 0); + + state->has_ci = true; + + break; + case ANYSEE_HW_508T2C: /* 20 */ + /* E7 T2C */ + + if (state->fe_id) + break; + + /* enable DVB-T/T2/C demod on IOE[5] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); if (ret) goto error; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config, - &adap->dev->i2c_adap, 0); + adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach, + &anysee_cxd2820r_config, &adap->dev->i2c_adap, + NULL); + + state->has_ci = true; break; } @@ -842,24 +917,26 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E30 */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), - NULL, DVB_PLL_THOMSON_DTT7579); + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, + (0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579); break; case ANYSEE_HW_507CD: /* 6 */ /* E30 Plus */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), - &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579); + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, + (0xc2 >> 1), &adap->dev->i2c_adap, + DVB_PLL_THOMSON_DTT7579); break; case ANYSEE_HW_507DC: /* 10 */ /* E30 C Plus */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc0 >> 1), - &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, + (0xc0 >> 1), &adap->dev->i2c_adap, + DVB_PLL_SAMSUNG_DTOS403IH102A); break; case ANYSEE_HW_507SI: /* 11 */ @@ -877,22 +954,12 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* Try first attach TDA18212 silicon tuner on IOE[4], if that * fails attach old simple PLL. */ - /* enable tuner on IOE[4] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); - if (ret) - goto error; - /* attach tuner */ fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, &adap->dev->i2c_adap, &anysee_tda18212_config); if (fe) break; - /* disable tuner on IOE[4] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10); - if (ret) - goto error; - /* attach tuner */ fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe, (0xc0 >> 1), &adap->dev->i2c_adap, @@ -904,11 +971,6 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E7 TC */ /* E7 PTC */ - /* enable tuner on IOE[4] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); - if (ret) - goto error; - /* attach tuner */ fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, &adap->dev->i2c_adap, &anysee_tda18212_config); @@ -930,6 +992,15 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) } break; + + case ANYSEE_HW_508T2C: /* 20 */ + /* E7 T2C */ + + /* attach tuner */ + fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, + &adap->dev->i2c_adap, &anysee_tda18212_config2); + + break; default: fe = NULL; } @@ -939,7 +1010,6 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) else ret = -ENODEV; -error: return ret; } @@ -969,6 +1039,201 @@ static int anysee_rc_query(struct dvb_usb_device *d) return 0; } +static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot, + int addr) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1}; + u8 val; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1); + if (ret) + return ret; + + return val; +} + +static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot, + int addr, u8 val) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val}; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot, + u8 addr) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1}; + u8 val; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1); + if (ret) + return ret; + + return val; +} + +static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot, + u8 addr, u8 val) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val}; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot) +{ + struct dvb_usb_device *d = ci->data; + int ret; + struct anysee_state *state = d->priv; + + state->ci_cam_ready = jiffies + msecs_to_jiffies(1000); + + ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80); + if (ret) + return ret; + + msleep(300); + + ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot) +{ + struct dvb_usb_device *d = ci->data; + int ret; + + ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80); + if (ret) + return ret; + + msleep(30); + + ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot) +{ + struct dvb_usb_device *d = ci->data; + int ret; + + ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot, + int open) +{ + struct dvb_usb_device *d = ci->data; + struct anysee_state *state = d->priv; + int ret; + u8 tmp; + + ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40); + if (ret) + return ret; + + if (tmp == 0) { + ret = DVB_CA_EN50221_POLL_CAM_PRESENT; + if (time_after(jiffies, state->ci_cam_ready)) + ret |= DVB_CA_EN50221_POLL_CAM_READY; + } + + return ret; +} + +static int anysee_ci_init(struct dvb_usb_device *d) +{ + struct anysee_state *state = d->priv; + int ret; + + state->ci.owner = THIS_MODULE; + state->ci.read_attribute_mem = anysee_ci_read_attribute_mem; + state->ci.write_attribute_mem = anysee_ci_write_attribute_mem; + state->ci.read_cam_control = anysee_ci_read_cam_control; + state->ci.write_cam_control = anysee_ci_write_cam_control; + state->ci.slot_reset = anysee_ci_slot_reset; + state->ci.slot_shutdown = anysee_ci_slot_shutdown; + state->ci.slot_ts_enable = anysee_ci_slot_ts_enable; + state->ci.poll_slot_status = anysee_ci_poll_slot_status; + state->ci.data = d; + + ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); + if (ret) + return ret; + + ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1); + if (ret) + return ret; + + return 0; +} + +static void anysee_ci_release(struct dvb_usb_device *d) +{ + struct anysee_state *state = d->priv; + + /* detach CI */ + if (state->has_ci) + dvb_ca_en50221_release(&state->ci); + + return; +} + +static int anysee_init(struct dvb_usb_device *d) +{ + struct anysee_state *state = d->priv; + int ret; + + /* LED light */ + ret = anysee_led_ctrl(d, 0x01, 0x03); + if (ret) + return ret; + + /* enable IR */ + ret = anysee_ir_ctrl(d, 1); + if (ret) + return ret; + + /* attach CI */ + if (state->has_ci) { + ret = anysee_ci_init(d); + if (ret) { + state->has_ci = false; + return ret; + } + } + + return 0; +} + /* DVB USB Driver stuff */ static struct dvb_usb_device_properties anysee_properties; @@ -1010,6 +1275,16 @@ static int anysee_probe(struct usb_interface *intf, return anysee_init(d); } +static void anysee_disconnect(struct usb_interface *intf) +{ + struct dvb_usb_device *d = usb_get_intfdata(intf); + + anysee_ci_release(d); + dvb_usb_device_exit(intf); + + return; +} + static struct usb_device_id anysee_table[] = { { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, @@ -1029,7 +1304,7 @@ static struct dvb_usb_device_properties anysee_properties = { { .num_frontends = 2, .frontend_ctrl = anysee_frontend_ctrl, - .fe = {{ + .fe = { { .streaming_ctrl = anysee_streaming_ctrl, .frontend_attach = anysee_frontend_attach, .tuner_attach = anysee_tuner_attach, @@ -1057,7 +1332,7 @@ static struct dvb_usb_device_properties anysee_properties = { } } }, - }}, + } }, } }, @@ -1087,7 +1362,7 @@ static struct dvb_usb_device_properties anysee_properties = { static struct usb_driver anysee_driver = { .name = "dvb_usb_anysee", .probe = anysee_probe, - .disconnect = dvb_usb_device_exit, + .disconnect = anysee_disconnect, .id_table = anysee_table, }; diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h index 57ee500b8c0..8ac87943154 100644 --- a/drivers/media/dvb/dvb-usb/anysee.h +++ b/drivers/media/dvb/dvb-usb/anysee.h @@ -36,6 +36,7 @@ #define DVB_USB_LOG_PREFIX "anysee" #include "dvb-usb.h" +#include "dvb_ca_en50221.h" #define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args) #define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args) @@ -54,12 +55,16 @@ enum cmd { CMD_GET_IR_CODE = 0x41, CMD_GET_HW_INFO = 0x19, CMD_SMARTCARD = 0x34, + CMD_CI = 0x37, }; struct anysee_state { u8 hw; /* PCB ID */ u8 seq; u8 fe_id:1; /* frondend ID */ + u8 has_ci:1; + struct dvb_ca_en50221 ci; + unsigned long ci_cam_ready; /* jiffies */ }; #define ANYSEE_HW_507T 2 /* E30 */ @@ -69,6 +74,7 @@ struct anysee_state { #define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */ #define ANYSEE_HW_508TC 18 /* E7 TC */ #define ANYSEE_HW_508S2 19 /* E7 S2 */ +#define ANYSEE_HW_508T2C 20 /* E7 T2C */ #define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */ #define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */ diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c index 9cd51ac1207..8a57ed8272d 100644 --- a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c +++ b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c @@ -40,9 +40,8 @@ * We replace errornous fields by default TPS fields (the ones with value 0). */ -static uint16_t compute_tps(struct dvb_frontend_parameters *p) +static uint16_t compute_tps(struct dtv_frontend_properties *op) { - struct dvb_ofdm_parameters *op = &p->u.ofdm; uint16_t tps = 0; switch (op->code_rate_HP) { @@ -83,7 +82,7 @@ static uint16_t compute_tps(struct dvb_frontend_parameters *p) /* tps |= (0 << 4) */; } - switch (op->constellation) { + switch (op->modulation) { case QAM_16: tps |= (1 << 13); break; @@ -119,7 +118,7 @@ static uint16_t compute_tps(struct dvb_frontend_parameters *p) /* tps |= (0 << 2) */; } - switch (op->hierarchy_information) { + switch (op->hierarchy) { case HIERARCHY_1: tps |= (1 << 10); break; @@ -263,9 +262,9 @@ static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe, return 0; } -static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct cinergyt2_fe_state *state = fe->demodulator_priv; struct dvbt_set_parameters_msg param; char result[2]; @@ -274,9 +273,20 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe, param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; param.tps = cpu_to_le16(compute_tps(fep)); param.freq = cpu_to_le32(fep->frequency / 1000); - param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ; param.flags = 0; + switch (fep->bandwidth_hz) { + case 8000000: + param.bandwidth = 0; + break; + case 7000000: + param.bandwidth = 1; + break; + case 6000000: + param.bandwidth = 2; + break; + } + err = dvb_usb_generic_rw(state->d, (char *)¶m, sizeof(param), result, sizeof(result), 0); @@ -286,12 +296,6 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe, return (err < 0) ? err : 0; } -static int cinergyt2_fe_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - return 0; -} - static void cinergyt2_fe_release(struct dvb_frontend *fe) { struct cinergyt2_fe_state *state = fe->demodulator_priv; @@ -316,9 +320,9 @@ struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d) static struct dvb_frontend_ops cinergyt2_fe_ops = { + .delsys = { SYS_DVBT }, .info = { .name = DRIVER_NAME, - .type = FE_OFDM, .frequency_min = 174000000, .frequency_max = 862000000, .frequency_stepsize = 166667, @@ -341,7 +345,6 @@ static struct dvb_frontend_ops cinergyt2_fe_ops = { .sleep = cinergyt2_fe_sleep, .set_frontend = cinergyt2_fe_set_frontend, - .get_frontend = cinergyt2_fe_get_frontend, .get_tune_settings = cinergyt2_fe_get_tune_settings, .read_status = cinergyt2_fe_read_status, diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 949ea1bc0aa..3940bb0f9ef 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -1067,18 +1067,17 @@ static struct dib0070_config dib7070p_dib0070_config = { }; struct dib0700_adapter_state { - int (*set_param_save) (struct dvb_frontend *, - struct dvb_frontend_parameters *); + int (*set_param_save) (struct dvb_frontend *); }; -static int dib7070_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int dib7070_set_param_override(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; u16 offset; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); switch (band) { case BAND_VHF: offset = 950; break; default: @@ -1087,7 +1086,7 @@ static int dib7070_set_param_override(struct dvb_frontend *fe, dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - return state->set_param_save(fe, fep); + return state->set_param_save(fe); } static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap) diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index 9bd6d51b3b9..7de125c0b36 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h @@ -48,6 +48,8 @@ struct dib0700_state { u8 disable_streaming_master_mode; u32 fw_version; u32 nb_packet_buffer_size; + int (*read_status)(struct dvb_frontend *, fe_status_t *); + int (*sleep)(struct dvb_frontend* fe); u8 buf[255]; }; diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index 206999476f0..070e82aa53f 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -834,6 +834,7 @@ static struct usb_driver dib0700_driver = { module_usb_driver(dib0700_driver); +MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw"); MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge"); MODULE_VERSION("1.0"); diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index f313182eb9d..f9e966aa26e 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -30,7 +30,7 @@ MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplif "if applicable for the device (default: 0=automatic/off)."); struct dib0700_adapter_state { - int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *); + int (*set_param_save) (struct dvb_frontend *); const struct firmware *frontend_firmware; }; @@ -804,13 +804,14 @@ static struct dib0070_config dib7770p_dib0070_config = { .charge_pump = 2, }; -static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib7070_set_param_override(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; u16 offset; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); switch (band) { case BAND_VHF: offset = 950; break; case BAND_UHF: @@ -818,17 +819,17 @@ static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_fronte } deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - return state->set_param_save(fe, fep); + return state->set_param_save(fe); } -static int dib7770_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int dib7770_set_param_override(struct dvb_frontend *fe) { - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct dib0700_adapter_state *state = adap->priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; u16 offset; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); switch (band) { case BAND_VHF: dib7000p_set_gpio(fe, 0, 0, 1); @@ -842,7 +843,7 @@ static int dib7770_set_param_override(struct dvb_frontend *fe, } deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - return state->set_param_save(fe, fep); + return state->set_param_save(fe); } static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap) @@ -1205,14 +1206,14 @@ static struct dib0070_config dib807x_dib0070_config[2] = { } }; -static int dib807x_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int dib807x_set_param_override(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; u16 offset = dib0070_wbd_offset(fe); - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); switch (band) { case BAND_VHF: offset += 750; @@ -1224,7 +1225,7 @@ static int dib807x_set_param_override(struct dvb_frontend *fe, deb_info("WBD for DiB8000: %d\n", offset); dib8000_set_wbd_ref(fe, offset); - return state->set_param_save(fe, fep); + return state->set_param_save(fe); } static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) @@ -1279,7 +1280,7 @@ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - 0x80); + 0x80, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); @@ -1308,7 +1309,7 @@ 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); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); @@ -1319,7 +1320,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) { /* initialize IC 1 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib807x_dib8000_config[1]); @@ -1328,7 +1329,7 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) } /* STK8096GP */ -struct dibx000_agc_config dib8090_agc_config[2] = { +static struct dibx000_agc_config dib8090_agc_config[2] = { { 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, @@ -1503,22 +1504,22 @@ static struct dib0090_config dib809x_dib0090_config = { .fref_clock_ratio = 6, }; -static int dib8096_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int dib8096_set_param_override(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); u16 target; int ret = 0; enum frontend_tune_state tune_state = CT_SHUTDOWN; u16 ltgain, rf_gain_limit; - ret = state->set_param_save(fe, fep); + ret = state->set_param_save(fe); if (ret < 0) return ret; - target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; + target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2; dib8000_set_wbd_ref(fe, target); @@ -1578,7 +1579,7 @@ 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); + dib8000_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]); @@ -1629,7 +1630,7 @@ 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); + dib8000_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]); if (adap->fe_adap[0].fe == NULL) @@ -1641,6 +1642,261 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) return fe_slave == NULL ? -ENODEV : 0; } +/* TFE8096P */ +static struct dibx000_agc_config dib8096p_agc_config[2] = { + { + .band_caps = BAND_UHF, + /* 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 */ + .setup = (0 << 15) | (0 << 14) | (5 << 11) + | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) + | (0 << 4) | (5 << 1) | (0 << 0), + + .inv_gain = 684, + .time_stabiliz = 10, + + .alpha_level = 0, + .thlock = 118, + + .wbd_inv = 0, + .wbd_ref = 1200, + .wbd_sel = 3, + .wbd_alpha = 5, + + .agc1_max = 65535, + .agc1_min = 0, + + .agc2_max = 32767, + .agc2_min = 0, + + .agc1_pt1 = 0, + .agc1_pt2 = 0, + .agc1_pt3 = 105, + .agc1_slope1 = 0, + .agc1_slope2 = 156, + .agc2_pt1 = 105, + .agc2_pt2 = 255, + .agc2_slope1 = 54, + .agc2_slope2 = 0, + + .alpha_mant = 28, + .alpha_exp = 26, + .beta_mant = 31, + .beta_exp = 51, + + .perform_agc_softsplit = 0, + } , { + .band_caps = BAND_FM | BAND_VHF | 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 */ + .setup = (0 << 15) | (0 << 14) | (5 << 11) + | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) + | (0 << 4) | (5 << 1) | (0 << 0), + + .inv_gain = 732, + .time_stabiliz = 10, + + .alpha_level = 0, + .thlock = 118, + + .wbd_inv = 0, + .wbd_ref = 1200, + .wbd_sel = 3, + .wbd_alpha = 5, + + .agc1_max = 65535, + .agc1_min = 0, + + .agc2_max = 32767, + .agc2_min = 0, + + .agc1_pt1 = 0, + .agc1_pt2 = 0, + .agc1_pt3 = 98, + .agc1_slope1 = 0, + .agc1_slope2 = 167, + .agc2_pt1 = 98, + .agc2_pt2 = 255, + .agc2_slope1 = 52, + .agc2_slope2 = 0, + + .alpha_mant = 28, + .alpha_exp = 26, + .beta_mant = 31, + .beta_exp = 51, + + .perform_agc_softsplit = 0, + } +}; + +static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = { + 108000, 13500, + 1, 9, 1, 0, 0, + 0, 0, 0, 0, 2, + (3 << 14) | (1 << 12) | (524 << 0), + (0 << 25) | 0, + 20199729, + 12000000, +}; + +static struct dib8000_config tfe8096p_dib8000_config = { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .update_lna = NULL, + + .agc_config_count = 2, + .agc = dib8096p_agc_config, + .pll = &dib8096p_clock_config_12_mhz, + + .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, + + .agc_control = NULL, + .diversity_delay = 48, + .output_mode = OUTMODE_MPEG2_FIFO, + .enMpegOutput = 1, +}; + +static struct dib0090_wbd_slope dib8096p_wbd_table[] = { + { 380, 81, 850, 64, 540, 4}, + { 860, 51, 866, 21, 375, 4}, + {1700, 0, 250, 0, 100, 6}, + {2600, 0, 250, 0, 100, 6}, + { 0xFFFF, 0, 0, 0, 0, 0}, +}; + +static const struct dib0090_config tfe8096p_dib0090_config = { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .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, + + .get_adc_power = dib8090_get_adc_power, + + .clkouttobamse = 1, + .analog_output = 0, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 1, + + .wbd = dib8096p_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + .force_cband_input = 0, +}; + +struct dibx090p_adc { + u32 freq; /* RF freq MHz */ + u32 timf; /* New Timf */ + u32 pll_loopdiv; /* New prediv */ + u32 pll_prediv; /* New loopdiv */ +}; + +struct dibx090p_adc dib8090p_adc_tab[] = { + { 50000, 17043521, 16, 3}, /* 64 MHz */ + {878000, 20199729, 9, 1}, /* 60 MHz */ + {0xffffffff, 0, 0, 0}, /* 60 MHz */ +}; + +static int dib8096p_agc_startup(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + struct dibx000_bandwidth_config pll; + u16 target; + int better_sampling_freq = 0, ret; + struct dibx090p_adc *adc_table = &dib8090p_adc_tab[0]; + + ret = state->set_param_save(fe); + if (ret < 0) + return ret; + memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); + + dib0090_pwm_gain_reset(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); + + + while (p->frequency / 1000 > adc_table->freq) { + better_sampling_freq = 1; + adc_table++; + } + + if ((adc_table->freq != 0xffffffff) && better_sampling_freq) { + pll.pll_ratio = adc_table->pll_loopdiv; + pll.pll_prediv = adc_table->pll_prediv; + dib8000_update_pll(fe, &pll); + dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc_table->timf); + } + return 0; +} + +static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap) +{ + 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); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(20); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + dib8000_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); + + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; +} + +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); + + 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->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; + return 0; +} + /* STK9090M */ static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { @@ -1883,7 +2139,7 @@ static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0) return -ENODEV; - dib0700_set_i2c_speed(adap->dev, 2000); + dib0700_set_i2c_speed(adap->dev, 1500); if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) return -ENODEV; release_firmware(state->frontend_firmware); @@ -1962,7 +2218,8 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0) return -ENODEV; - dib0700_set_i2c_speed(adap->dev, 2000); + + dib0700_set_i2c_speed(adap->dev, 1500); if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) return -ENODEV; @@ -1975,7 +2232,7 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL) return -ENODEV; fe_slave->dvb = adap->fe_adap[0].fe->dvb; - dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 2000); + dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 1500); if (dib9000_firmware_post_pll_init(fe_slave) < 0) return -ENODEV; } @@ -2064,7 +2321,7 @@ static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_ return 0; } -static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib7090_agc_startup(struct dvb_frontend *fe) { struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; @@ -2073,13 +2330,13 @@ static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_para struct dib7090p_best_adc adc; int ret; - ret = state->set_param_save(fe, fep); + ret = state->set_param_save(fe); if (ret < 0) return ret; memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); dib0090_pwm_gain_reset(fe); - target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2; + target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; dib7000p_set_wbd_ref(fe, target); if (dib7090p_get_best_sampling(fe, &adc) == 0) { @@ -2092,6 +2349,49 @@ static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_para return 0; } +static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) +{ + deb_info("AGC restart callback: %d", restart); + if (restart == 0) /* before AGC startup */ + dib0090_set_dc_servo(fe, 1); + return 0; +} + +static int dib7090e_update_lna(struct dvb_frontend *fe, u16 agc_global) +{ + u16 agc1 = 0, agc2, wbd = 0, wbd_target, wbd_offset, threshold_agc1; + s16 wbd_delta; + + if ((fe->dtv_property_cache.frequency) < 400000000) + threshold_agc1 = 25000; + else + threshold_agc1 = 30000; + + wbd_target = (dib0090_get_wbd_target(fe)*8+1)/2; + wbd_offset = dib0090_get_wbd_offset(fe); + dib7000p_get_agc_values(fe, NULL, &agc1, &agc2, &wbd); + wbd_delta = (s16)wbd - (((s16)wbd_offset+10)*4) ; + + deb_info("update lna, agc_global=%d agc1=%d agc2=%d", + agc_global, agc1, agc2); + deb_info("update lna, wbd=%d wbd target=%d wbd offset=%d wbd delta=%d", + wbd, wbd_target, wbd_offset, wbd_delta); + + if ((agc1 < threshold_agc1) && (wbd_delta > 0)) { + dib0090_set_switch(fe, 1, 1, 1); + dib0090_set_vga(fe, 0); + dib0090_update_rframp_7090(fe, 0); + dib0090_update_tuning_table_7090(fe, 0); + } else { + dib0090_set_vga(fe, 1); + dib0090_update_rframp_7090(fe, 1); + dib0090_update_tuning_table_7090(fe, 1); + dib0090_set_switch(fe, 0, 0, 0); + } + + return 0; +} + static struct dib0090_wbd_slope dib7090_wbd_table[] = { { 380, 81, 850, 64, 540, 4}, { 860, 51, 866, 21, 375, 4}, @@ -2100,7 +2400,16 @@ static struct dib0090_wbd_slope dib7090_wbd_table[] = { { 0xFFFF, 0, 0, 0, 0, 0}, }; -struct dibx000_agc_config dib7090_agc_config[2] = { +static struct dib0090_wbd_slope dib7090e_wbd_table[] = { + { 380, 81, 850, 64, 540, 4}, + { 700, 51, 866, 21, 320, 4}, + { 860, 48, 666, 18, 330, 6}, + {1700, 0, 250, 0, 100, 6}, + {2600, 0, 250, 0, 100, 6}, + { 0xFFFF, 0, 0, 0, 0, 0}, +}; + +static struct dibx000_agc_config dib7090_agc_config[2] = { { .band_caps = BAND_UHF, /* 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, @@ -2278,6 +2587,34 @@ static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = { } }; +static struct dib7000p_config tfe7090e_dib7000p_config = { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .tuner_is_baseband = 1, + .update_lna = dib7090e_update_lna, + + .agc_config_count = 2, + .agc = dib7090_agc_config, + + .bw = &dib7090_clock_config_12_mhz, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .pwm_freq_div = 0, + + .agc_control = dib7090_agc_restart, + + .spur_protect = 0, + .disable_sample_and_hold = 0, + .enable_current_mirror = 0, + .diversity_delay = 0, + + .output_mode = OUTMODE_MPEG2_FIFO, + .enMpegOutput = 1, +}; + static const struct dib0090_config nim7090_dib0090_config = { .io.clock_khz = 12000, .io.pll_bypass = 0, @@ -2312,6 +2649,107 @@ static const struct dib0090_config nim7090_dib0090_config = { .in_soc = 1, }; +static const struct dib0090_config tfe7090e_dib0090_config = { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .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, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 0, + + .wbd = dib7090e_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + .force_cband_input = 1, + .is_dib7090e = 1, +}; + +static struct dib7000p_config tfe7790e_dib7000p_config = { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .tuner_is_baseband = 1, + .update_lna = dib7090e_update_lna, + + .agc_config_count = 2, + .agc = dib7090_agc_config, + + .bw = &dib7090_clock_config_12_mhz, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .pwm_freq_div = 0, + + .agc_control = dib7090_agc_restart, + + .spur_protect = 0, + .disable_sample_and_hold = 0, + .enable_current_mirror = 0, + .diversity_delay = 0, + + .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, + .enMpegOutput = 1, +}; + +static const struct dib0090_config tfe7790e_dib0090_config = { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .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, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 0, + + .wbd = dib7090e_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + .force_cband_input = 1, + .is_dib7090e = 1, + .force_crystal_mode = 1, +}; + static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { { .io.clock_khz = 12000, @@ -2504,6 +2942,97 @@ static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap) return 0; } +static int tfe7090e_frontend_attach(struct dvb_usb_adapter *adap) +{ + 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); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + msleep(20); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, + 1, 0x10, &tfe7090e_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + 0x80, &tfe7090e_dib7000p_config); + + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; +} + +static int tfe7790e_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_state *st = adap->dev->priv; + + /* The TFE7790E requires the dib0700 to not be in master mode */ + st->disable_streaming_master_mode = 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); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + msleep(20); + dib0700_ctrl_clock(adap->dev, 72, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, + 1, 0x10, &tfe7790e_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + 0x80, &tfe7790e_dib7000p_config); + + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; +} + +static int tfe7790e_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); + + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, + &tfe7790e_dib0090_config) == NULL) + return -ENODEV; + + dib7000p_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; + return 0; +} + +static int tfe7090e_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); + + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, + &tfe7090e_dib0090_config) == NULL) + return -ENODEV; + + dib7000p_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; + return 0; +} + /* STK7070PD */ static struct dib7000p_config stk7070pd_dib7000p_config[2] = { { @@ -2537,19 +3066,25 @@ static struct dib7000p_config stk7070pd_dib7000p_config[2] = { } }; -static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) +static void stk7070pd_init(struct dvb_usb_device *dev) { - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + dib0700_set_gpio(dev, GPIO6, GPIO_OUT, 1); msleep(10); - dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + dib0700_set_gpio(dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 0); - dib0700_ctrl_clock(adap->dev, 72, 1); + dib0700_ctrl_clock(dev, 72, 1); msleep(10); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 1); +} + +static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) +{ + stk7070pd_init(adap->dev); + msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); @@ -2570,6 +3105,77 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap) return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } +static int novatd_read_status_override(struct dvb_frontend *fe, + fe_status_t *stat) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dvb_usb_device *dev = adap->dev; + struct dib0700_state *state = dev->priv; + int ret; + + ret = state->read_status(fe, stat); + + if (!ret) + dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, + !!(*stat & FE_HAS_LOCK)); + + return ret; +} + +static int novatd_sleep_override(struct dvb_frontend* fe) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dvb_usb_device *dev = adap->dev; + struct dib0700_state *state = dev->priv; + + /* turn off LED */ + dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, 0); + + return state->sleep(fe); +} + +/** + * novatd_frontend_attach - Nova-TD specific attach + * + * Nova-TD has GPIO0, 1 and 2 for LEDs. So do not fiddle with them except for + * information purposes. + */ +static int novatd_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dvb_usb_device *dev = adap->dev; + struct dib0700_state *st = dev->priv; + + if (adap->id == 0) { + stk7070pd_init(dev); + + /* turn the power LED on, the other two off (just in case) */ + dib0700_set_gpio(dev, GPIO0, GPIO_OUT, 0); + 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, + stk7070pd_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } + } + + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap, + adap->id == 0 ? 0x80 : 0x82, + &stk7070pd_dib7000p_config[adap->id]); + + if (adap->fe_adap[0].fe == NULL) + return -ENODEV; + + st->read_status = adap->fe_adap[0].fe->ops.read_status; + adap->fe_adap[0].fe->ops.read_status = novatd_read_status_override; + st->sleep = adap->fe_adap[0].fe->ops.sleep; + adap->fe_adap[0].fe->ops.sleep = novatd_sleep_override; + + return 0; +} + /* S5H1411 */ static struct s5h1411_config pinnacle_801e_config = { .output_mode = S5H1411_PARALLEL_OUTPUT, @@ -2960,6 +3566,9 @@ struct usb_device_id dib0700_usb_id_table[] = { /* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790E) }, +/* 80 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE8096P) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -3338,6 +3947,57 @@ struct dvb_usb_device_properties dib0700_devices[] = { .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .frontend_attach = novatd_frontend_attach, + .tuner_attach = dib7070p_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + }}, + .size_of_priv = sizeof(struct dib0700_adapter_state), + }, { + .num_frontends = 1, + .fe = {{ + .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 = novatd_frontend_attach, + .tuner_attach = dib7070p_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x03), + }}, + .size_of_priv = sizeof(struct dib0700_adapter_state), + } + }, + + .num_device_descs = 1, + .devices = { + { "Hauppauge Nova-TD Stick (52009)", + { &dib0700_usb_id_table[35], 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, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + + .num_adapters = 2, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .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, @@ -3360,7 +4020,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { } }, - .num_device_descs = 6, + .num_device_descs = 5, .devices = { { "DiBcom STK7070PD reference design", { &dib0700_usb_id_table[17], NULL }, @@ -3370,10 +4030,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[18], NULL }, { NULL }, }, - { "Hauppauge Nova-TD Stick (52009)", - { &dib0700_usb_id_table[35], NULL }, - { NULL }, - }, { "Hauppauge Nova-TD-500 (84xxx)", { &dib0700_usb_id_table[36], NULL }, { NULL }, @@ -4025,6 +4681,127 @@ struct dvb_usb_device_properties dib0700_devices[] = { RC_TYPE_NEC, .change_protocol = dib0700_change_protocol, }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .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 = tfe7090e_frontend_attach, + .tuner_attach = tfe7090e_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + } }, + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom TFE7090E reference design", + { &dib0700_usb_id_table[78], 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, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .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 = tfe7790e_frontend_attach, + .tuner_attach = tfe7790e_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x03), + } }, + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom TFE7790E reference design", + { &dib0700_usb_id_table[79], 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, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk80xx_pid_filter, + .pid_filter_ctrl = stk80xx_pid_filter_ctrl, + .frontend_attach = tfe8096p_frontend_attach, + .tuner_attach = tfe8096p_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + } }, + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom TFE8096P reference design", + { &dib0700_usb_id_table[80], 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, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, }, }; diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 0a9a79820f2..ff34419a4c8 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -118,12 +118,12 @@ static struct mt352_config digitv_mt352_config = { .demod_init = digitv_mt352_demod_init, }; -static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe) { struct dvb_usb_adapter *adap = fe->dvb->priv; u8 b[5]; - fe->ops.tuner_ops.calc_regs(fe, fep, b, sizeof(b)); + fe->ops.tuner_ops.calc_regs(fe, b, sizeof(b)); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0); diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c index 17413adec7a..3d81daa4917 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c @@ -16,7 +16,7 @@ struct dtt200u_fe_state { fe_status_t stat; - struct dvb_frontend_parameters fep; + struct dtv_frontend_properties fep; struct dvb_frontend frontend; }; @@ -100,22 +100,27 @@ static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_fron return 0; } -static int dtt200u_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int dtt200u_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dtt200u_fe_state *state = fe->demodulator_priv; int i; fe_status_t st; u16 freq = fep->frequency / 250000; u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 }; - switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break; - case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break; - case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break; - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: - return -EINVAL; + switch (fep->bandwidth_hz) { + case 8000000: + bwbuf[1] = 8; + break; + case 7000000: + bwbuf[1] = 7; + break; + case 6000000: + bwbuf[1] = 6; + break; + default: + return -EINVAL; } dvb_usb_generic_write(state->d,bwbuf,2); @@ -134,11 +139,11 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend* fe, return 0; } -static int dtt200u_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int dtt200u_fe_get_frontend(struct dvb_frontend* fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dtt200u_fe_state *state = fe->demodulator_priv; - memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters)); + memcpy(fep, &state->fep, sizeof(struct dtv_frontend_properties)); return 0; } @@ -172,9 +177,9 @@ error: } static struct dvb_frontend_ops dtt200u_fe_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "WideView USB DVB-T", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 250000, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index ba4a7517354..ddf282f355b 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c @@ -141,11 +141,17 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) goto err_dmx_dev; } - dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx); + if ((ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, + &adap->demux.dmx)) < 0) { + err("dvb_net_init failed: error %d",ret); + goto err_net_init; + } adap->state |= DVB_USB_ADAP_STATE_DVB; return 0; +err_net_init: + dvb_dmxdev_release(&adap->dmxdev); err_dmx_dev: dvb_dmx_release(&adap->demux); err_dmx: diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 2d08c9b5128..d390ddaa5a5 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -109,10 +109,13 @@ #define USB_PID_DIBCOM_STK807XPVR 0x1f98 #define USB_PID_DIBCOM_STK8096GP 0x1fa0 #define USB_PID_DIBCOM_NIM8096MD 0x1fa8 +#define USB_PID_DIBCOM_TFE8096P 0x1f9C #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 #define USB_PID_DIBCOM_STK7770P 0x1e80 #define USB_PID_DIBCOM_NIM7090 0x1bb2 #define USB_PID_DIBCOM_TFE7090PVR 0x1bb4 +#define USB_PID_DIBCOM_TFE7090E 0x1bb7 +#define USB_PID_DIBCOM_TFE7790E 0x1e6e #define USB_PID_DIBCOM_NIM9090M 0x2383 #define USB_PID_DIBCOM_NIM9090MD 0x2384 #define USB_PID_DPOSH_M9206_COLD 0x9206 @@ -128,6 +131,8 @@ #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 #define USB_PID_INTEL_CE9500 0x9500 #define USB_PID_ITETECH_IT9135 0x9135 +#define USB_PID_ITETECH_IT9135_9005 0x9005 +#define USB_PID_ITETECH_IT9135_9006 0x9006 #define USB_PID_KWORLD_399U 0xe399 #define USB_PID_KWORLD_399U_2 0xe400 #define USB_PID_KWORLD_395U 0xe396 @@ -322,6 +327,7 @@ #define USB_PID_TVWAY_PLUS 0x0002 #define USB_PID_SVEON_STV20 0xe39d #define USB_PID_SVEON_STV22 0xe401 +#define USB_PID_SVEON_STV22_IT9137 0xe411 #define USB_PID_AZUREWAVE_AZ6027 0x3275 #define USB_PID_TERRATEC_DVBS2CI_V1 0x10a4 #define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index ff941d20e6b..451c5a7adfb 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1435,22 +1435,40 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) return 0; } +enum dw2102_table_entry { + CYPRESS_DW2102, + CYPRESS_DW2101, + CYPRESS_DW2104, + TEVII_S650, + TERRATEC_CINERGY_S, + CYPRESS_DW3101, + TEVII_S630, + PROF_1100, + TEVII_S660, + PROF_7500, + GENIATECH_SU3000, + TERRATEC_CINERGY_S2, + TEVII_S480_1, + TEVII_S480_2, + X3M_SPC1400HD, +}; + static struct usb_device_id dw2102_table[] = { - {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, - {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, - {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)}, - {USB_DEVICE(0x9022, USB_PID_TEVII_S650)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, - {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, - {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, - {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, - {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, - {USB_DEVICE(0x3034, 0x7500)}, - {USB_DEVICE(0x1f4d, 0x3000)}, - {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)}, - {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, - {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, - {USB_DEVICE(0x1f4d, 0x3100)}, + [CYPRESS_DW2102] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, + [CYPRESS_DW2101] = {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, + [CYPRESS_DW2104] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)}, + [TEVII_S650] = {USB_DEVICE(0x9022, USB_PID_TEVII_S650)}, + [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, + [CYPRESS_DW3101] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, + [TEVII_S630] = {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, + [PROF_1100] = {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, + [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, + [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)}, + [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)}, + [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)}, + [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, + [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, + [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)}, { } }; @@ -1610,15 +1628,15 @@ static struct dvb_usb_device_properties dw2102_properties = { .num_device_descs = 3, .devices = { {"DVBWorld DVB-S 2102 USB2.0", - {&dw2102_table[0], NULL}, + {&dw2102_table[CYPRESS_DW2102], NULL}, {NULL}, }, {"DVBWorld DVB-S 2101 USB2.0", - {&dw2102_table[1], NULL}, + {&dw2102_table[CYPRESS_DW2101], NULL}, {NULL}, }, {"TerraTec Cinergy S USB", - {&dw2102_table[4], NULL}, + {&dw2102_table[TERRATEC_CINERGY_S], NULL}, {NULL}, }, } @@ -1664,11 +1682,11 @@ static struct dvb_usb_device_properties dw2104_properties = { .num_device_descs = 2, .devices = { { "DVBWorld DW2104 USB2.0", - {&dw2102_table[2], NULL}, + {&dw2102_table[CYPRESS_DW2104], NULL}, {NULL}, }, { "TeVii S650 USB2.0", - {&dw2102_table[3], NULL}, + {&dw2102_table[TEVII_S650], NULL}, {NULL}, }, } @@ -1715,7 +1733,7 @@ static struct dvb_usb_device_properties dw3101_properties = { .num_device_descs = 1, .devices = { { "DVBWorld DVB-C 3101 USB2.0", - {&dw2102_table[5], NULL}, + {&dw2102_table[CYPRESS_DW3101], NULL}, {NULL}, }, } @@ -1761,7 +1779,7 @@ static struct dvb_usb_device_properties s6x0_properties = { .num_device_descs = 1, .devices = { {"TeVii S630 USB", - {&dw2102_table[6], NULL}, + {&dw2102_table[TEVII_S630], NULL}, {NULL}, }, } @@ -1770,33 +1788,33 @@ static struct dvb_usb_device_properties s6x0_properties = { struct dvb_usb_device_properties *p1100; static struct dvb_usb_device_description d1100 = { "Prof 1100 USB ", - {&dw2102_table[7], NULL}, + {&dw2102_table[PROF_1100], NULL}, {NULL}, }; struct dvb_usb_device_properties *s660; static struct dvb_usb_device_description d660 = { "TeVii S660 USB", - {&dw2102_table[8], NULL}, + {&dw2102_table[TEVII_S660], NULL}, {NULL}, }; static struct dvb_usb_device_description d480_1 = { "TeVii S480.1 USB", - {&dw2102_table[12], NULL}, + {&dw2102_table[TEVII_S480_1], NULL}, {NULL}, }; static struct dvb_usb_device_description d480_2 = { "TeVii S480.2 USB", - {&dw2102_table[13], NULL}, + {&dw2102_table[TEVII_S480_2], NULL}, {NULL}, }; struct dvb_usb_device_properties *p7500; static struct dvb_usb_device_description d7500 = { "Prof 7500 USB DVB-S2", - {&dw2102_table[9], NULL}, + {&dw2102_table[PROF_7500], NULL}, {NULL}, }; @@ -1842,15 +1860,15 @@ static struct dvb_usb_device_properties su3000_properties = { .num_device_descs = 3, .devices = { { "SU3000HD DVB-S USB2.0", - { &dw2102_table[10], NULL }, + { &dw2102_table[GENIATECH_SU3000], NULL }, { NULL }, }, { "Terratec Cinergy S2 USB HD", - { &dw2102_table[11], NULL }, + { &dw2102_table[TERRATEC_CINERGY_S2], NULL }, { NULL }, }, { "X3M TV SPC1400HD PCI", - { &dw2102_table[14], NULL }, + { &dw2102_table[X3M_SPC1400HD], NULL }, { NULL }, }, } @@ -1859,12 +1877,11 @@ static struct dvb_usb_device_properties su3000_properties = { static int dw2102_probe(struct usb_interface *intf, const struct usb_device_id *id) { - p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + p1100 = kmemdup(&s6x0_properties, + sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!p1100) return -ENOMEM; /* copy default structure */ - memcpy(p1100, &s6x0_properties, - sizeof(struct dvb_usb_device_properties)); /* fill only different fields */ p1100->firmware = "dvb-usb-p1100.fw"; p1100->devices[0] = d1100; @@ -1872,13 +1889,12 @@ static int dw2102_probe(struct usb_interface *intf, p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach; - s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + s660 = kmemdup(&s6x0_properties, + sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!s660) { kfree(p1100); return -ENOMEM; } - memcpy(s660, &s6x0_properties, - sizeof(struct dvb_usb_device_properties)); s660->firmware = "dvb-usb-s660.fw"; s660->num_device_descs = 3; s660->devices[0] = d660; @@ -1886,14 +1902,13 @@ static int dw2102_probe(struct usb_interface *intf, s660->devices[2] = d480_2; s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach; - p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + p7500 = kmemdup(&s6x0_properties, + sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!p7500) { kfree(p1100); kfree(s660); return -ENOMEM; } - memcpy(p7500, &s6x0_properties, - sizeof(struct dvb_usb_device_properties)); p7500->firmware = "dvb-usb-p7500.fw"; p7500->devices[0] = d7500; p7500->rc.legacy.rc_map_table = rc_map_tbs_table; diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c index 015b4e8af1a..90a70c66a96 100644 --- a/drivers/media/dvb/dvb-usb/friio-fe.c +++ b/drivers/media/dvb/dvb-usb/friio-fe.c @@ -282,23 +282,24 @@ static int jdvbt90502_set_property(struct dvb_frontend *fe, return r; } -static int jdvbt90502_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int jdvbt90502_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; p->inversion = INVERSION_AUTO; - p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - p->u.ofdm.code_rate_HP = FEC_AUTO; - p->u.ofdm.code_rate_LP = FEC_AUTO; - p->u.ofdm.constellation = QAM_64; - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; - p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; - p->u.ofdm.hierarchy_information = HIERARCHY_AUTO; + p->bandwidth_hz = 6000000; + p->code_rate_HP = FEC_AUTO; + p->code_rate_LP = FEC_AUTO; + p->modulation = QAM_64; + p->transmission_mode = TRANSMISSION_MODE_AUTO; + p->guard_interval = GUARD_INTERVAL_AUTO; + p->hierarchy = HIERARCHY_AUTO; return 0; } -static int jdvbt90502_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int jdvbt90502_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + /** * NOTE: ignore all the parameters except frequency. * others should be fixed to the proper value for ISDB-T, @@ -438,14 +439,12 @@ error: } static struct dvb_frontend_ops jdvbt90502_ops = { - + .delsys = { SYS_ISDBT }, .info = { .name = "Comtech JDVBT90502 ISDB-T", - .type = FE_OFDM, .frequency_min = 473000000, /* UHF 13ch, center */ .frequency_max = 767142857, /* UHF 62ch, center */ - .frequency_stepsize = JDVBT90502_PLL_CLK / - JDVBT90502_PLL_DIVIDER, + .frequency_stepsize = JDVBT90502_PLL_CLK / JDVBT90502_PLL_DIVIDER, .frequency_tolerance = 0, /* NOTE: this driver ignores all parameters but frequency. */ diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c index 5426267980c..67957dd99ed 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c +++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c @@ -113,28 +113,12 @@ static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front return 0; } -static int gp8psk_fe_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - deb_fe("%s(..)\n", __func__); - return 0; -} - -static int gp8psk_fe_get_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - deb_fe("%s(..)\n", __func__); - return 0; -} - - -static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int gp8psk_fe_set_frontend(struct dvb_frontend *fe) { struct gp8psk_fe_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; u8 cmd[10]; - u32 freq = fep->frequency * 1000; + u32 freq = c->frequency * 1000; int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct); deb_fe("%s()\n", __func__); @@ -342,9 +326,9 @@ success: static struct dvb_frontend_ops gp8psk_fe_ops = { + .delsys = { SYS_DVBS }, .info = { .name = "Genpix DVB-S", - .type = FE_QPSK, .frequency_min = 800000, .frequency_max = 2250000, .frequency_stepsize = 100, @@ -366,8 +350,6 @@ static struct dvb_frontend_ops gp8psk_fe_ops = { .init = NULL, .sleep = NULL, - .set_property = gp8psk_fe_set_property, - .get_property = gp8psk_fe_get_property, .set_frontend = gp8psk_fe_set_frontend, .get_tune_settings = gp8psk_fe_get_tune_settings, diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index 67094b879bb..9f01cd7a6e3 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -52,42 +52,59 @@ static int pid_filter; module_param_named(pid, pid_filter, int, 0644); MODULE_PARM_DESC(pid, "set default 0=on 1=off"); +static int dvb_usb_it913x_firmware; +module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644); +MODULE_PARM_DESC(firmware, "set firmware 0=auto 1=IT9137 2=IT9135V1"); + + int cmd_counter; DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct it913x_state { u8 id; -}; - -struct ite_config { - u8 chip_ver; - u16 chip_type; - u32 firmware; - u8 tuner_id_0; - u8 tuner_id_1; - u8 dual_mode; + struct ite_config it913x_config; }; struct ite_config it913x_config; +#define IT913X_RETRY 10 +#define IT913X_SND_TIMEOUT 100 +#define IT913X_RCV_TIMEOUT 200 + static int it913x_bulk_write(struct usb_device *dev, u8 *snd, int len, u8 pipe) { - int ret, actual_l; + int ret, actual_l, i; + + for (i = 0; i < IT913X_RETRY; i++) { + ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), + snd, len , &actual_l, IT913X_SND_TIMEOUT); + if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT) + break; + } + + if (len != actual_l && ret == 0) + ret = -EAGAIN; - ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), - snd, len , &actual_l, 100); return ret; } static int it913x_bulk_read(struct usb_device *dev, u8 *rev, int len, u8 pipe) { - int ret, actual_l; + int ret, actual_l, i; + + for (i = 0; i < IT913X_RETRY; i++) { + ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), + rev, len , &actual_l, IT913X_RCV_TIMEOUT); + if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT) + break; + } + + if (len != actual_l && ret == 0) + ret = -EAGAIN; - ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), - rev, len , &actual_l, 200); return ret; } @@ -100,7 +117,7 @@ static u16 check_sum(u8 *p, u8 len) return ~sum; } -static int it913x_io(struct usb_device *udev, u8 mode, u8 pro, +static int it913x_usb_talk(struct usb_device *udev, u8 mode, u8 pro, u8 cmd, u32 reg, u8 addr, u8 *data, u8 len) { int ret = 0, i, buf_size = 1; @@ -159,22 +176,41 @@ static int it913x_io(struct usb_device *udev, u8 mode, u8 pro, buff[buf_size++] = (chk_sum & 0xff); ret = it913x_bulk_write(udev, buff, buf_size , 0x02); + if (ret < 0) + goto error; - ret |= it913x_bulk_read(udev, buff, (mode & 1) ? + ret = it913x_bulk_read(udev, buff, (mode & 1) ? 5 : len + 5 , 0x01); + if (ret < 0) + goto error; rlen = (mode & 0x1) ? 0x1 : len; if (mode & 1) - ret |= buff[2]; + ret = buff[2]; else memcpy(data, &buff[3], rlen); cmd_counter++; - kfree(buff); +error: kfree(buff); - return (ret < 0) ? -ENODEV : 0; + return ret; +} + +static int it913x_io(struct usb_device *udev, u8 mode, u8 pro, + u8 cmd, u32 reg, u8 addr, u8 *data, u8 len) +{ + int ret, i; + + for (i = 0; i < IT913X_RETRY; i++) { + ret = it913x_usb_talk(udev, mode, pro, + cmd, reg, addr, data, len); + if (ret != -EAGAIN) + break; + } + + return ret; } static int it913x_wr_reg(struct usb_device *udev, u8 pro, u32 reg , u8 data) @@ -223,15 +259,15 @@ static u32 it913x_query(struct usb_device *udev, u8 pro) static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) { - int ret = 0; + struct usb_device *udev = adap->dev->udev; + int ret; u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) return -EAGAIN; deb_info(1, "PID_C (%02x)", onoff); - if (!onoff) - ret = it913x_wr_reg(adap->dev->udev, pro, PID_RST, 0x1); + ret = it913x_wr_reg(udev, pro, PID_EN, onoff); mutex_unlock(&adap->dev->i2c_mutex); return ret; @@ -241,27 +277,20 @@ static int it913x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) { struct usb_device *udev = adap->dev->udev; - int ret = 0; + int ret; u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; - if (pid_filter > 0) - return 0; - if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) return -EAGAIN; deb_info(1, "PID_F (%02x)", onoff); - if (onoff) { - ret = it913x_wr_reg(udev, pro, PID_EN, 0x1); - - ret |= it913x_wr_reg(udev, pro, PID_LSB, (u8)(pid & 0xff)); - ret |= it913x_wr_reg(udev, pro, PID_MSB, (u8)(pid >> 8)); + ret = it913x_wr_reg(udev, pro, PID_LSB, (u8)(pid & 0xff)); - ret |= it913x_wr_reg(udev, pro, PID_INX_EN, (u8)onoff); + ret |= it913x_wr_reg(udev, pro, PID_MSB, (u8)(pid >> 8)); - ret |= it913x_wr_reg(udev, pro, PID_INX, (u8)(index & 0x1f)); + ret |= it913x_wr_reg(udev, pro, PID_INX_EN, (u8)onoff); - } + ret |= it913x_wr_reg(udev, pro, PID_INX, (u8)(index & 0x1f)); mutex_unlock(&adap->dev->i2c_mutex); return 0; @@ -337,15 +366,73 @@ static int it913x_rc_query(struct dvb_usb_device *d) if ((ibuf[2] + ibuf[3]) == 0xff) { key = ibuf[2]; - key += ibuf[0] << 8; - deb_info(1, "INT Key =%08x", key); + key += ibuf[0] << 16; + key += ibuf[1] << 8; + deb_info(1, "NEC Extended Key =%08x", key); if (d->rc_dev != NULL) rc_keydown(d->rc_dev, key, 0); } + mutex_unlock(&d->i2c_mutex); return ret; } + +/* Firmware sets raw */ +const char fw_it9135_v1[] = "dvb-usb-it9135-01.fw"; +const char fw_it9135_v2[] = "dvb-usb-it9135-02.fw"; +const char fw_it9137[] = "dvb-usb-it9137-01.fw"; + +static int ite_firmware_select(struct usb_device *udev, + struct dvb_usb_device_properties *props) +{ + int sw; + /* auto switch */ + if (le16_to_cpu(udev->descriptor.idProduct) == + USB_PID_ITETECH_IT9135) + sw = IT9135_V1_FW; + else if (le16_to_cpu(udev->descriptor.idProduct) == + USB_PID_ITETECH_IT9135_9005) + sw = IT9135_V1_FW; + else if (le16_to_cpu(udev->descriptor.idProduct) == + USB_PID_ITETECH_IT9135_9006) { + sw = IT9135_V2_FW; + if (it913x_config.tuner_id_0 == 0) + it913x_config.tuner_id_0 = IT9135_60; + } else + sw = IT9137_FW; + + /* force switch */ + if (dvb_usb_it913x_firmware != IT9135_AUTO) + sw = dvb_usb_it913x_firmware; + + switch (sw) { + case IT9135_V1_FW: + it913x_config.firmware_ver = 1; + it913x_config.adc_x2 = 1; + props->firmware = fw_it9135_v1; + break; + case IT9135_V2_FW: + it913x_config.firmware_ver = 1; + it913x_config.adc_x2 = 1; + props->firmware = fw_it9135_v2; + break; + case IT9137_FW: + default: + it913x_config.firmware_ver = 0; + it913x_config.adc_x2 = 0; + props->firmware = fw_it9137; + } + + return 0; +} + +#define TS_MPEG_PKT_SIZE 188 +#define EP_LOW 21 +#define TS_BUFFER_SIZE_PID (EP_LOW*TS_MPEG_PKT_SIZE) +#define EP_HIGH 348 +#define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE) + static int it913x_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, @@ -359,6 +446,19 @@ static int it913x_identify_state(struct usb_device *udev, /* checnk for dual mode */ it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5); + if (udev->speed != USB_SPEED_HIGH) { + props->adapter[0].fe[0].pid_filter_count = 5; + info("USB 1 low speed mode - connect to USB 2 port"); + if (pid_filter > 0) + pid_filter = 0; + if (it913x_config.dual_mode) { + it913x_config.dual_mode = 0; + info("Dual mode not supported in USB 1"); + } + } else /* For replugging */ + if(props->adapter[0].fe[0].pid_filter_count == 5) + props->adapter[0].fe[0].pid_filter_count = 31; + /* TODO different remotes */ remote = it913x_read_reg(udev, 0x49ac); /* Remote */ if (remote == 0) @@ -370,6 +470,28 @@ static int it913x_identify_state(struct usb_device *udev, info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode , remote, it913x_config.tuner_id_0); + /* Select Stream Buffer Size and pid filter option*/ + if (pid_filter) { + props->adapter[0].fe[0].stream.u.bulk.buffersize = + TS_BUFFER_SIZE_MAX; + props->adapter[0].fe[0].caps &= + ~DVB_USB_ADAP_NEED_PID_FILTERING; + } else + props->adapter[0].fe[0].stream.u.bulk.buffersize = + TS_BUFFER_SIZE_PID; + + if (it913x_config.dual_mode) { + props->adapter[1].fe[0].stream.u.bulk.buffersize = + props->adapter[0].fe[0].stream.u.bulk.buffersize; + props->num_adapters = 2; + if (pid_filter) + props->adapter[1].fe[0].caps = + props->adapter[0].fe[0].caps; + } else + props->num_adapters = 1; + + ret = ite_firmware_select(udev, props); + if (firm_no > 0) { *cold = 0; return 0; @@ -391,18 +513,22 @@ static int it913x_identify_state(struct usb_device *udev, ret = it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0); } - props->num_adapters = 2; - } else - props->num_adapters = 1; + } reg = it913x_read_reg(udev, IO_MUX_POWER_CLK); if (it913x_config.dual_mode) { ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); - ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); + if (it913x_config.firmware_ver == 1) + ret |= it913x_wr_reg(udev, DEV_0, 0xcfff, 0x1); + else + ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); } else { ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0); - ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0); + if (it913x_config.firmware_ver == 1) + ret |= it913x_wr_reg(udev, DEV_0, 0xcfff, 0x0); + else + ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0); } *cold = 1; @@ -428,35 +554,45 @@ static int it913x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return ret; } - static int it913x_download_firmware(struct usb_device *udev, const struct firmware *fw) { - int ret = 0, i; - u8 packet_size, dlen; + int ret = 0, i = 0, pos = 0; + u8 packet_size, min_pkt; u8 *fw_data; - packet_size = 0x29; - ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100); info("FRM Starting Firmware Download"); - /* This uses scatter write firmware headers follow */ - /* 03 XX 00 XX = chip number? */ - - for (i = 0; i < fw->size; i += packet_size) { - if (i > 0) - packet_size = 0x39; - fw_data = (u8 *)(fw->data + i); - dlen = ((i + packet_size) > fw->size) - ? (fw->size - i) : packet_size; - ret |= it913x_io(udev, WRITE_DATA, DEV_0, - CMD_SCATTER_WRITE, 0, 0, fw_data, dlen); - udelay(1000); + + /* Multi firmware loader */ + /* This uses scatter write firmware headers */ + /* The firmware must start with 03 XX 00 */ + /* and be the extact firmware length */ + + if (it913x_config.chip_ver == 2) + min_pkt = 0x11; + else + min_pkt = 0x19; + + while (i <= fw->size) { + if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0)) + || (i == fw->size)) { + packet_size = i - pos; + if ((packet_size > min_pkt) || (i == fw->size)) { + fw_data = (u8 *)(fw->data + pos); + pos += packet_size; + if (packet_size > 0) + ret |= it913x_io(udev, WRITE_DATA, + DEV_0, CMD_SCATTER_WRITE, 0, + 0, fw_data, packet_size); + udelay(1000); + } + } + i++; } - ret |= it913x_io(udev, WRITE_CMD, DEV_0, - CMD_BOOT, 0, 0, NULL, 0); + ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); msleep(100); @@ -474,12 +610,17 @@ static int it913x_download_firmware(struct usb_device *udev, /* Tuner function */ if (it913x_config.dual_mode) ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); - - ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); - ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); - if (it913x_config.dual_mode) { - ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); - ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); + else + ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0x68); + + if ((it913x_config.chip_ver == 1) && + (it913x_config.chip_type == 0x9135)) { + ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); + ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); + if (it913x_config.dual_mode) { + ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); + ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); + } } return (ret < 0) ? -ENODEV : 0; @@ -500,32 +641,23 @@ static int it913x_name(struct dvb_usb_adapter *adap) static int it913x_frontend_attach(struct dvb_usb_adapter *adap) { struct usb_device *udev = adap->dev->udev; + struct it913x_state *st = adap->dev->priv; int ret = 0; - u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); - u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize; - u8 tuner_id, tuner_type; + u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize / 4; + u8 pkt_size = 0x80; + + if (adap->dev->udev->speed != USB_SPEED_HIGH) + pkt_size = 0x10; + + it913x_config.adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); if (adap->id == 0) - tuner_id = it913x_config.tuner_id_0; - else - tuner_id = it913x_config.tuner_id_1; - - /* TODO we always use IT9137 possible references here*/ - /* Documentation suggests don't care */ - switch (tuner_id) { - case 0x51: - case 0x52: - case 0x60: - case 0x61: - case 0x62: - default: - case 0x38: - tuner_type = IT9137; - } + memcpy(&st->it913x_config, &it913x_config, + sizeof(struct ite_config)); adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach, - &adap->dev->i2c_adap, adap_addr, adf, tuner_type); + &adap->dev->i2c_adap, adap_addr, &st->it913x_config); if (adap->id == 0 && adap->fe_adap[0].fe) { ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1); @@ -536,13 +668,13 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap) ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_LSB, ep_size & 0xff); ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8); - ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, 0x80); + ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, pkt_size); } else if (adap->id == 1 && adap->fe_adap[0].fe) { ret = it913x_wr_reg(udev, DEV_0, EP0_TX_EN, 0x6f); ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_LSB, ep_size & 0xff); ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8); - ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, 0x80); + ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, pkt_size); ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF2_EN, 0x1); ret = it913x_wr_reg(udev, DEV_1_DMOD, MP2IF_SERIAL, 0x1); ret = it913x_wr_reg(udev, DEV_1, TOP_HOSTB_SER_MODE, 0x1); @@ -582,6 +714,9 @@ static int it913x_probe(struct usb_interface *intf, static struct usb_device_id it913x_table[] = { { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) }, { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) }, + { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137) }, + { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005) }, + { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006) }, {} /* Terminating entry */ }; @@ -614,8 +749,8 @@ static struct dvb_usb_device_properties it913x_properties = { .endpoint = 0x04, .u = {/* Keep Low if PID filter on */ .bulk = { - .buffersize = 3584, - + .buffersize = + TS_BUFFER_SIZE_PID, } } } @@ -639,8 +774,8 @@ static struct dvb_usb_device_properties it913x_properties = { .endpoint = 0x05, .u = { .bulk = { - .buffersize = 3584, - + .buffersize = + TS_BUFFER_SIZE_PID, } } } @@ -654,10 +789,10 @@ static struct dvb_usb_device_properties it913x_properties = { .rc_query = it913x_rc_query, .rc_interval = IT913X_POLL, .allowed_protos = RC_TYPE_NEC, - .rc_codes = RC_MAP_KWORLD_315U, + .rc_codes = RC_MAP_MSI_DIGIVOX_III, }, .i2c_algo = &it913x_i2c_algo, - .num_device_descs = 2, + .num_device_descs = 5, .devices = { { "Kworld UB499-2T T09(IT9137)", { &it913x_table[0], NULL }, @@ -665,6 +800,15 @@ static struct dvb_usb_device_properties it913x_properties = { { "ITE 9135 Generic", { &it913x_table[1], NULL }, }, + { "Sveon STV22 Dual DVB-T HDTV(IT9137)", + { &it913x_table[2], NULL }, + }, + { "ITE 9135(9005) Generic", + { &it913x_table[3], NULL }, + }, + { "ITE 9135(9006) Generic", + { &it913x_table[4], NULL }, + }, } }; @@ -679,5 +823,5 @@ module_usb_driver(it913x_driver); MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.07"); +MODULE_VERSION("1.22"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index 1a876a65ed5..b3fe05bbffc 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c @@ -388,8 +388,7 @@ static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__, pid, index, onoff); - if (onoff) - if (!pid_filter) { + if (onoff) { ret = mutex_lock_interruptible(&adap->dev->i2c_mutex); if (ret < 0) return -EAGAIN; @@ -654,6 +653,9 @@ static int lme2510_identify_state(struct usb_device *udev, struct dvb_usb_device_description **desc, int *cold) { + if (pid_filter > 0) + props->adapter[0].fe[0].caps &= + ~DVB_USB_ADAP_NEED_PID_FILTERING; *cold = 0; return 0; } @@ -1293,5 +1295,5 @@ module_usb_driver(lme2510_driver); MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); -MODULE_VERSION("1.90"); +MODULE_VERSION("1.91"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.c b/drivers/media/dvb/dvb-usb/mxl111sf-demod.c index d1f58371c71..d83df4bb72d 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-demod.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-demod.c @@ -102,8 +102,8 @@ fail: } static -int mxl1x1sf_demod_get_tps_constellation(struct mxl111sf_demod_state *state, - fe_modulation_t *constellation) +int mxl1x1sf_demod_get_tps_modulation(struct mxl111sf_demod_state *state, + fe_modulation_t *modulation) { u8 val; int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val); @@ -113,13 +113,13 @@ int mxl1x1sf_demod_get_tps_constellation(struct mxl111sf_demod_state *state, switch ((val & V6_PARAM_CONSTELLATION_MASK) >> 4) { case 0: - *constellation = QPSK; + *modulation = QPSK; break; case 1: - *constellation = QAM_16; + *modulation = QAM_16; break; case 2: - *constellation = QAM_64; + *modulation = QAM_64; break; } fail: @@ -284,8 +284,7 @@ static int mxl1x1sf_demod_reset_irq_status(struct mxl111sf_demod_state *state) /* ------------------------------------------------------------------------ */ -static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe) { struct mxl111sf_demod_state *state = fe->demodulator_priv; int ret = 0; @@ -303,7 +302,7 @@ static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe, mxl_dbg("()"); if (fe->ops.tuner_ops.set_params) { - ret = fe->ops.tuner_ops.set_params(fe, param); + ret = fe->ops.tuner_ops.set_params(fe); if (mxl_fail(ret)) goto fail; msleep(50); @@ -481,13 +480,13 @@ static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { struct mxl111sf_demod_state *state = fe->demodulator_priv; - fe_modulation_t constellation; + fe_modulation_t modulation; u16 snr; mxl111sf_demod_calc_snr(state, &snr); - mxl1x1sf_demod_get_tps_constellation(state, &constellation); + mxl1x1sf_demod_get_tps_modulation(state, &modulation); - switch (constellation) { + switch (modulation) { case QPSK: *signal_strength = (snr >= 1300) ? min(65535, snr * 44) : snr * 38; @@ -508,9 +507,9 @@ static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe, return 0; } -static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct mxl111sf_demod_state *state = fe->demodulator_priv; mxl_dbg("()"); @@ -518,18 +517,18 @@ static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe, p->inversion = /* FIXME */ ? INVERSION_ON : INVERSION_OFF; #endif if (fe->ops.tuner_ops.get_bandwidth) - fe->ops.tuner_ops.get_bandwidth(fe, &p->u.ofdm.bandwidth); + fe->ops.tuner_ops.get_bandwidth(fe, &p->bandwidth_hz); if (fe->ops.tuner_ops.get_frequency) fe->ops.tuner_ops.get_frequency(fe, &p->frequency); - mxl1x1sf_demod_get_tps_code_rate(state, &p->u.ofdm.code_rate_HP); - mxl1x1sf_demod_get_tps_code_rate(state, &p->u.ofdm.code_rate_LP); - mxl1x1sf_demod_get_tps_constellation(state, &p->u.ofdm.constellation); + mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_HP); + mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_LP); + mxl1x1sf_demod_get_tps_modulation(state, &p->modulation); mxl1x1sf_demod_get_tps_guard_fft_mode(state, - &p->u.ofdm.transmission_mode); + &p->transmission_mode); mxl1x1sf_demod_get_tps_guard_interval(state, - &p->u.ofdm.guard_interval); + &p->guard_interval); mxl1x1sf_demod_get_tps_hierarchy(state, - &p->u.ofdm.hierarchy_information); + &p->hierarchy); return 0; } @@ -551,10 +550,9 @@ static void mxl111sf_demod_release(struct dvb_frontend *fe) } static struct dvb_frontend_ops mxl111sf_demod_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "MaxLinear MxL111SF DVB-T demodulator", - .type = FE_OFDM, .frequency_min = 177000000, .frequency_max = 858000000, .frequency_stepsize = 166666, diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c index a6341058c4e..72db6eef4b9 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c @@ -38,6 +38,8 @@ struct mxl111sf_tuner_state { struct mxl111sf_tuner_config *cfg; + enum mxl_if_freq if_freq; + u32 frequency; u32 bandwidth; }; @@ -186,7 +188,10 @@ static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state) ctrl = iffcw & 0x00ff; #endif ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl); - mxl_fail(ret); + if (mxl_fail(ret)) + goto fail; + + state->if_freq = state->cfg->if_freq; fail: return ret; } @@ -267,55 +272,49 @@ static int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state *state, /* ------------------------------------------------------------------------ */ -static int mxl111sf_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int mxl111sf_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 delsys = c->delivery_system; struct mxl111sf_tuner_state *state = fe->tuner_priv; int ret; u8 bw; mxl_dbg("()"); - if (fe->ops.info.type == FE_ATSC) { - switch (params->u.vsb.modulation) { - case VSB_8: - case VSB_16: - bw = 0; /* ATSC */ - break; - case QAM_64: - case QAM_256: - bw = 1; /* US CABLE */ - break; - default: - err("%s: modulation not set!", __func__); - return -EINVAL; - } - } else if (fe->ops.info.type == FE_OFDM) { - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: + switch (delsys) { + case SYS_ATSC: + bw = 0; /* ATSC */ + break; + case SYS_DVBC_ANNEX_B: + bw = 1; /* US CABLE */ + break; + case SYS_DVBT: + switch (c->bandwidth_hz) { + case 6000000: bw = 6; break; - case BANDWIDTH_7_MHZ: + case 7000000: bw = 7; break; - case BANDWIDTH_8_MHZ: + case 8000000: bw = 8; break; default: err("%s: bandwidth not set!", __func__); return -EINVAL; } - } else { + break; + default: err("%s: modulation type not supported!", __func__); return -EINVAL; } - ret = mxl1x1sf_tune_rf(fe, params->frequency, bw); + ret = mxl1x1sf_tune_rf(fe, c->frequency, bw); if (mxl_fail(ret)) goto fail; - state->frequency = params->frequency; - state->bandwidth = (fe->ops.info.type == FE_OFDM) ? - params->u.ofdm.bandwidth : 0; + state->frequency = c->frequency; + state->bandwidth = c->bandwidth_hz; fail: return ret; } @@ -407,6 +406,54 @@ static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) return 0; } +static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe, + u32 *frequency) +{ + struct mxl111sf_tuner_state *state = fe->tuner_priv; + + *frequency = 0; + + switch (state->if_freq) { + case MXL_IF_4_0: /* 4.0 MHz */ + *frequency = 4000000; + break; + case MXL_IF_4_5: /* 4.5 MHz */ + *frequency = 4500000; + break; + case MXL_IF_4_57: /* 4.57 MHz */ + *frequency = 4570000; + break; + case MXL_IF_5_0: /* 5.0 MHz */ + *frequency = 5000000; + break; + case MXL_IF_5_38: /* 5.38 MHz */ + *frequency = 5380000; + break; + case MXL_IF_6_0: /* 6.0 MHz */ + *frequency = 6000000; + break; + case MXL_IF_6_28: /* 6.28 MHz */ + *frequency = 6280000; + break; + case MXL_IF_7_2: /* 7.2 MHz */ + *frequency = 7200000; + break; + case MXL_IF_35_25: /* 35.25 MHz */ + *frequency = 35250000; + break; + case MXL_IF_36: /* 36 MHz */ + *frequency = 36000000; + break; + case MXL_IF_36_15: /* 36.15 MHz */ + *frequency = 36150000; + break; + case MXL_IF_44: /* 44 MHz */ + *frequency = 44000000; + break; + } + return 0; +} + static int mxl111sf_tuner_release(struct dvb_frontend *fe) { struct mxl111sf_tuner_state *state = fe->tuner_priv; @@ -436,6 +483,7 @@ static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = { .get_rf_strength = mxl111sf_get_rf_strength, .get_frequency = mxl111sf_tuner_get_frequency, .get_bandwidth = mxl111sf_tuner_get_bandwidth, + .get_if_frequency = mxl111sf_tuner_get_if_frequency, .release = mxl111sf_tuner_release, }; diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c index 825a8b242e0..38ef0253d3b 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf.c @@ -758,6 +758,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); #define MXL111SF_EP4_BULK_STREAMING_CONFIG \ + .size_of_priv = sizeof(struct mxl111sf_adap_state), \ .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ .stream = { \ .type = USB_BULK, \ @@ -772,6 +773,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); /* FIXME: works for v6 but not v8 silicon */ #define MXL111SF_EP4_ISOC_STREAMING_CONFIG \ + .size_of_priv = sizeof(struct mxl111sf_adap_state), \ .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ .stream = { \ .type = USB_ISOC, \ @@ -788,6 +790,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); } #define MXL111SF_EP6_BULK_STREAMING_CONFIG \ + .size_of_priv = sizeof(struct mxl111sf_adap_state), \ .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ .stream = { \ .type = USB_BULK, \ @@ -802,6 +805,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); /* FIXME */ #define MXL111SF_EP6_ISOC_STREAMING_CONFIG \ + .size_of_priv = sizeof(struct mxl111sf_adap_state), \ .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ .stream = { \ .type = USB_ISOC, \ @@ -839,8 +843,6 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = { .fe_ioctl_override = mxl111sf_fe_ioctl_override, .num_frontends = 1, .fe = {{ - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_attach_demod, .tuner_attach = mxl111sf_attach_tuner, @@ -883,8 +885,6 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = { .fe_ioctl_override = mxl111sf_fe_ioctl_override, .num_frontends = 1, .fe = {{ - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_attach_demod, .tuner_attach = mxl111sf_attach_tuner, @@ -927,16 +927,12 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = { .fe_ioctl_override = mxl111sf_fe_ioctl_override, .num_frontends = 2, .fe = {{ - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_lgdt3305_frontend_attach, .tuner_attach = mxl111sf_attach_tuner, MXL111SF_EP6_BULK_STREAMING_CONFIG, }, { - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_attach_demod, .tuner_attach = mxl111sf_attach_tuner, @@ -992,16 +988,12 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = { .fe_ioctl_override = mxl111sf_fe_ioctl_override, .num_frontends = 2, .fe = {{ - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_lgdt3305_frontend_attach, .tuner_attach = mxl111sf_attach_tuner, MXL111SF_EP6_ISOC_STREAMING_CONFIG, }, { - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_attach_demod, .tuner_attach = mxl111sf_attach_tuner, diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c index 56acf8e55d5..e53a1061cb8 100644 --- a/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/drivers/media/dvb/dvb-usb/ttusb2.c @@ -75,10 +75,18 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) { struct ttusb2_state *st = d->priv; - u8 s[wlen+4],r[64] = { 0 }; + u8 *s, *r = NULL; int ret = 0; - memset(s,0,wlen+4); + s = kzalloc(wlen+4, GFP_KERNEL); + if (!s) + return -ENOMEM; + + r = kzalloc(64, GFP_KERNEL); + if (!r) { + kfree(s); + return -ENOMEM; + } s[0] = 0xaa; s[1] = ++st->id; @@ -94,12 +102,17 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, r[2] != cmd || (rlen > 0 && r[3] != rlen)) { warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]); + kfree(s); + kfree(r); return -EIO; } if (rlen > 0) memcpy(rbuf, &r[4], rlen); + kfree(s); + kfree(r); + return 0; } @@ -384,7 +397,7 @@ static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num memcpy(&obuf[3], msg[i].buf, msg[i].len); - if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) { + if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) { err("i2c transfer failed."); break; } diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c index 2bb8d4cc8d8..5eab468dd90 100644 --- a/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c @@ -135,9 +135,9 @@ static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front return 0; } -static int vp702x_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int vp702x_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct vp702x_fe_state *st = fe->demodulator_priv; struct vp702x_device_state *dst = st->d->priv; u32 freq = fep->frequency/1000; @@ -155,14 +155,14 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe, cmd[1] = freq & 0xff; cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */ - sr = (u64) (fep->u.qpsk.symbol_rate/1000) << 20; + sr = (u64) (fep->symbol_rate/1000) << 20; do_div(sr,88000); cmd[3] = (sr >> 12) & 0xff; cmd[4] = (sr >> 4) & 0xff; cmd[5] = (sr << 4) & 0xf0; deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %lu (%lx)\n", - fep->frequency,freq,freq, fep->u.qpsk.symbol_rate, + fep->frequency, freq, freq, fep->symbol_rate, (unsigned long) sr, (unsigned long) sr); /* if (fep->inversion == INVERSION_ON) @@ -171,7 +171,7 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe, if (st->voltage == SEC_VOLTAGE_18) cmd[6] |= 0x40; -/* if (fep->u.qpsk.symbol_rate > 8000000) +/* if (fep->symbol_rate > 8000000) cmd[6] |= 0x20; if (fep->frequency < 1531000) @@ -211,13 +211,6 @@ static int vp702x_fe_sleep(struct dvb_frontend *fe) return 0; } -static int vp702x_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - deb_fe("%s\n",__func__); - return 0; -} - static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *m) { @@ -350,9 +343,9 @@ error: static struct dvb_frontend_ops vp702x_fe_ops = { + .delsys = { SYS_DVBS }, .info = { .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1000, /* kHz for QPSK frontends */ @@ -371,7 +364,6 @@ static struct dvb_frontend_ops vp702x_fe_ops = { .sleep = vp702x_fe_sleep, .set_frontend = vp702x_fe_set_frontend, - .get_frontend = vp702x_fe_get_frontend, .get_tune_settings = vp702x_fe_get_tune_settings, .read_status = vp702x_fe_read_status, diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c index 8452eef9032..b8825b18c00 100644 --- a/drivers/media/dvb/dvb-usb/vp7045-fe.c +++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c @@ -103,9 +103,9 @@ static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front return 0; } -static int vp7045_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int vp7045_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct vp7045_fe_state *state = fe->demodulator_priv; u8 buf[5]; u32 freq = fep->frequency / 1000; @@ -115,25 +115,24 @@ static int vp7045_fe_set_frontend(struct dvb_frontend* fe, buf[2] = freq & 0xff; buf[3] = 0; - switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: buf[4] = 8; break; - case BANDWIDTH_7_MHZ: buf[4] = 7; break; - case BANDWIDTH_6_MHZ: buf[4] = 6; break; - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: - return -EINVAL; + switch (fep->bandwidth_hz) { + case 8000000: + buf[4] = 8; + break; + case 7000000: + buf[4] = 7; + break; + case 6000000: + buf[4] = 6; + break; + default: + return -EINVAL; } vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200); return 0; } -static int vp7045_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - return 0; -} - static void vp7045_fe_release(struct dvb_frontend* fe) { struct vp7045_fe_state *state = fe->demodulator_priv; @@ -159,9 +158,9 @@ error: static struct dvb_frontend_ops vp7045_fe_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "Twinhan VP7045/46 USB DVB-T", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 1000, @@ -181,7 +180,6 @@ static struct dvb_frontend_ops vp7045_fe_ops = { .sleep = vp7045_fe_sleep, .set_frontend = vp7045_fe_set_frontend, - .get_frontend = vp7045_fe_get_frontend, .get_tune_settings = vp7045_fe_get_tune_settings, .read_status = vp7045_fe_read_status, |