diff options
Diffstat (limited to 'linux')
-rw-r--r-- | linux/drivers/media/dvb/dibusb/Kconfig | 8 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c | 245 |
2 files changed, 232 insertions, 21 deletions
diff --git a/linux/drivers/media/dvb/dibusb/Kconfig b/linux/drivers/media/dvb/dibusb/Kconfig index a6d41043a..642e1e49d 100644 --- a/linux/drivers/media/dvb/dibusb/Kconfig +++ b/linux/drivers/media/dvb/dibusb/Kconfig @@ -1,12 +1,13 @@ config DVB_DIBUSB - tristate "DiBcom USB DVB-T devices (see help for device list)" + tristate "DiBcom USB DVB-T devices (see help for a complete device list)" depends on DVB_CORE && USB select FW_LOADER select DVB_DIB3000MB select DVB_DIB3000MC + select DVB_MT352 help Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by - DiBcom (http://www.dibcom.fr). + DiBcom (http://www.dibcom.fr) and C&E. Devices supported by this driver: @@ -14,13 +15,14 @@ config DVB_DIBUSB TwinhanDTV Magic Box (VP7041e) KWorld V-Stream XPERT DTV - DVB-T USB Hama DVB-T USB-Box - DiBcom reference device (non-public) + DiBcom reference devices (non-public) Ultima Electronic/Artec T1 USB TVBOX Compro Videomate DVB-U2000 - DVB-T USB Grandtec DVB-T USB Avermedia AverTV DVBT USB Artec T1 USB1.1 and USB2.0 boxes Yakumo/Typhoon DVB-T USB2.0 + Hanftek UMT-010 USB2.0 The VP7041 seems to be identical to "CTS Portable" (Chinese Television System). diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/linux/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c index 863835692..ee476baa1 100644 --- a/linux/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c +++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c @@ -70,6 +70,34 @@ static u32 dibusb_i2c_func(struct i2c_adapter *adapter) return I2C_FUNC_I2C; } +int lg_tdtp_e102p_tua6034(struct dvb_frontend *fe, struct + dvb_frontend_parameters* fep, u8 *pllbuf); + +static int lg_tdtp_e102p_mt352_demod_init(struct dvb_frontend *fe) +{ + static u8 mt352_clock_config [] = { 0x89, 0xb0, 0x2d }; + static u8 mt352_reset [] = { 0x50, 0x80 }; + static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; + static u8 mt352_agc_cfg [] = { 0x67, 0x14, 0x22 }; + static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; + + mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); + udelay(2000); + mt352_write(fe, mt352_reset, sizeof(mt352_reset)); + mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); + + mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); + mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); + + return 0; +} + +static struct mt352_config lg_tdtp_e102p_tua6034_config = { + .demod_address = 0x1e, + .demod_init = lg_tdtp_e102p_mt352_demod_init, + .pll_set = lg_tdtp_e102p_tua6034, +}; + static struct i2c_algorithm dibusb_algo = { .name = "DiBcom USB i2c algorithm", .id = I2C_ALGO_BIT, @@ -83,15 +111,15 @@ int dibusb_fe_init(struct usb_dibusb* dib) int i; if (dib->init_state & DIBUSB_STATE_I2C) - for (i = 0; i < sizeof(dib->dibdev->parm->demod_i2c_addrs) / sizeof(unsigned char) && - dib->dibdev->parm->demod_i2c_addrs[i] != 0; i++) { + for (i = 0; i < sizeof(dib->dibdev->dev_cl->demod_i2c_addrs) / sizeof(unsigned char) && + dib->dibdev->dev_cl->demod_i2c_addrs[i] != 0; i++) { - demod_cfg.demod_address = dib->dibdev->parm->demod_i2c_addrs[i]; - demod_cfg.pll_addr = dib->dibdev->parm->pll_addr; - demod_cfg.pll_set = dib->dibdev->parm->pll_set; + demod_cfg.demod_address = dib->dibdev->dev_cl->demod_i2c_addrs[i]; + demod_cfg.pll_addr = dib->dibdev->dev_cl->pll_addr; + demod_cfg.pll_set = dib->dibdev->dev_cl->pll_set; demod_cfg.pll_init = NULL; - switch (dib->dibdev->parm->type) { + switch (dib->dibdev->dev_cl->id) { case DIBUSB1_1: case DIBUSB1_1_AN2235: dib->fe = dib3000mb_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops); @@ -99,6 +127,9 @@ int dibusb_fe_init(struct usb_dibusb* dib) case DIBUSB2_0: dib->fe = dib3000mc_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops); break; + case UMT2_0: + dib->fe = mt352_attach(&lg_tdtp_e102p_tua6034_config, &dib->i2c_adap); + break; } if (dib->fe != NULL) { info("found demodulator at i2c address 0x%x",demod_cfg.demod_address); @@ -129,6 +160,8 @@ int dibusb_fe_exit(struct usb_dibusb *dib) return 0; } + + int dibusb_i2c_init(struct usb_dibusb *dib) { int ret = 0; @@ -151,7 +184,13 @@ int dibusb_i2c_init(struct usb_dibusb *dib) err("could not add i2c adapter"); dib->init_state |= DIBUSB_STATE_I2C; - + + u8 b[2] = { 0xff , 0xff }; + dibusb_i2c_msg(dib, 0x10, b,2, NULL, 0); + + b[0] = 0x05; + b[1] = 0x01; + dibusb_i2c_msg(dib, 0x10, b,2, NULL, 0); return ret; } @@ -164,27 +203,26 @@ int dibusb_i2c_exit(struct usb_dibusb *dib) } - /* pll stuff, maybe removed soon (thx to Gerd/Andrew in advance) */ -int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct - dvb_frontend_parameters* params) +int thomson_cable_eu_pll_set(struct dvb_frontend *fe, struct + dvb_frontend_parameters *fep) { struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv; u8 buf[4]; struct i2c_msg msg = { - .addr = dib->dibdev->parm->pll_addr, + .addr = dib->dibdev->dev_cl->pll_addr, .flags = 0, .buf = buf, .len = sizeof(buf) }; - u32 tfreq = (params->frequency + 36125000) / 62500; + u32 tfreq = (fep->frequency + 36125000) / 62500; int vu,p0,p1,p2; - if (params->frequency > 403250000) + if (fep->frequency > 403250000) vu = 1, p2 = 1, p1 = 0, p0 = 1; - else if (params->frequency > 115750000) + else if (fep->frequency > 115750000) vu = 0, p2 = 1, p1 = 1, p0 = 0; - else if (params->frequency > 44250000) + else if (fep->frequency > 44250000) vu = 0, p2 = 0, p1 = 1, p0 = 1; else return -EINVAL; @@ -202,15 +240,15 @@ int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct } int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend *fe, struct - dvb_frontend_parameters *params) + dvb_frontend_parameters *fep) { struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv; u8 buf[4]; - u32 freq = params->frequency; + u32 freq = fep->frequency; u32 tfreq = ((freq + 36125000)*6 + 500000) / 1000000; u8 TA, T210, R210, ctrl1, cp210, p4321; struct i2c_msg msg = { - .addr = dib->dibdev->parm->pll_addr, + .addr = dib->dibdev->dev_cl->pll_addr, .flags = 0, .buf = buf, .len = sizeof(buf) @@ -255,3 +293,174 @@ int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend *fe, struct return 0; } +/* + * 7 6 5 4 3 2 1 0 + * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0 + * + * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8 + * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0 + * + * Control byte 1 1 T/A=1 T2 T1 T0 R2 R1 R0 + * 1 T/A=0 0 0 ATC AL2 AL1 AL0 + * + * Control byte 2 CP2 CP1 CP0 BS5 BS4 BS3 BS2 BS1 + * + * MA0/1 = programmable address bits + * R/~W = read/write bit (0 for writing) + * N14-0 = programmable LO frequency + * + * T/A = test AGC bit (0 = next 6 bits AGC setting, + * 1 = next 6 bits test and reference divider ratio settings) + * T2-0 = test bits + * R2-0 = reference divider ratio and programmable frequency step + * ATC = AGC current setting and time constant + * ATC = 0: AGC current = 220nA, AGC time constant = 2s + * ATC = 1: AGC current = 9uA, AGC time constant = 50ms + * AL2-0 = AGC take-over point bits + * CP2-0 = charge pump current + * BS5-1 = PMOS ports control bits; + * BSn = 0 corresponding port is off, high-impedance state (at power-on) + * BSn = 1 corresponding port is on + */ + +/* +int panasonic_cofdm_env77h11d5_tda6650_init(struct dvb_frontend *fe, u8 pllbuf[4]) +{ + + +} +*/ + +/* +int panasonic_cofdm_env77h11d5_tda6650_set (struct dvb_frontend *fe, struct + dvb_frontend_parameters *fep,u8 pllbuf[4]) +{ + u8 tuner_buf[4]; + struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = + sizeof(tuner_buf) }; + int tuner_frequency = 0; + u8 band, cp, filter; + + // determine charge pump + tuner_frequency = params->frequency + 36166000; + if (tuner_frequency < 87000000) + return -EINVAL; + else if (tuner_frequency < 130000000) + cp = 3; + else if (tuner_frequency < 160000000) + cp = 5; + else if (tuner_frequency < 200000000) + cp = 6; + else if (tuner_frequency < 290000000) + cp = 3; + else if (tuner_frequency < 420000000) + cp = 5; + else if (tuner_frequency < 480000000) + cp = 6; + else if (tuner_frequency < 620000000) + cp = 3; + else if (tuner_frequency < 830000000) + cp = 5; + else if (tuner_frequency < 895000000) + cp = 7; + else + return -EINVAL; + + // determine band + if (params->frequency < 49000000) + return -EINVAL; + else if (params->frequency < 161000000) + band = 1; + else if (params->frequency < 444000000) + band = 2; + else if (params->frequency < 861000000) + band = 4; + else + return -EINVAL; + + // setup PLL filter + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + filter = 0; + break; + + case BANDWIDTH_7_MHZ: + filter = 0; + break; + + case BANDWIDTH_8_MHZ: + filter = 1; + break; + + default: + return -EINVAL; + } + + // calculate divisor + // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6) + tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000; + + // setup tuner buffer + tuner_buf[0] = (tuner_frequency >> 8) & 0x7f; + tuner_buf[1] = tuner_frequency & 0xff; + tuner_buf[2] = 0xca; + tuner_buf[3] = (cp << 5) | (filter << 3) | band; + +*/ +/* + * 7 6 5 4 3 2 1 0 + * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0 + * + * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8 + * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0 + * + * Control byte 1 CP T2 T1 T0 RSA RSB OS + * + * Band Switch byte X X X P4 P3 P2 P1 P0 + * + * Auxiliary byte ATC AL2 AL1 AL0 0 0 0 0 + * + * Address: MA1 MA0 Address + * 0 0 c0 + * 0 1 c2 (always valid) + * 1 0 c4 + * 1 1 c6 + * + * + * + */ + +int lg_tdtp_e102p_tua6034(struct dvb_frontend *fe, struct + dvb_frontend_parameters* fep, u8 *pllbuf) +{ + u32 div; + u8 p3210, p4; + +#define TUNER_MUL 62500 + + deb_info("tdtp debug %d MHz, BW: %d\n",fep->frequency,fep->u.ofdm.bandwidth); + + div = (fep->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL; + + pllbuf[0] = 0xc2; + pllbuf[1] = (div >> 8) & 0x7f; + pllbuf[2] = div & 0xff; + pllbuf[3] = 0xce; + + if (fep->frequency < 174500000) + p3210 = 1; // not supported by the tdtp_e102p + else if (fep->frequency < 230000000) // VHF + p3210 = 2; + else + p3210 = 4; + + if (fep->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) + p4 = 0; + else + p4 = 1; + + pllbuf[4] = (p4 << 4) | p3210; + deb_info("pllbuf[4] = %x\n",pllbuf[4]); + + return 0; +} |