Here is my patch to put the code for the fmd1216me tuner into dvb-pll. I addresses the cx88 and saa7134 drivers. I didn't fix the cxusb driver since there's still some stuff I'm not sure about there. All the effected boards (see patch description) should work as least as well as they did before. Some should improve, either in analog mode or digital mode or both, as they will gain sleep and init sequences they missed out on before. One board in cx88 was sending an init sequence on every tune, which shouldn't be necessary, and probably counter productive since the init sequence would tune to some bogus frequency before tuning to the correct one. dvb/frontends/dvb-pll.c | 10 ++- video/cx88/cx88-dvb.c | 63 ------------------- video/saa7134/saa7134-dvb.c | 140 +------------------------------------------- 3 files changed, 16 insertions(+), 197 deletions(-) ----- Integrate (almost) all users of the fmd1216 tuner with dvb-pll From: Trent Piepho <xyzzy@xxxxxxxxxxxxx> Enhance the dvb-pll definition of the fmd1216 tuner by adding an init sequence and a sleep sequence. The init sequence sets the AGC control register to 0xa0, selecting the fast time constant and 112 dBuV take-over point. This the recommended value for DVB-T operation. The sleep sequence sets bit P4 (which is believed to turn the analog demodulator on), turns off the tuning voltage, and sets the AGC control register to 0x60 (external AGC voltage, the recommended value for analog operation). The existing dvb-pll users in the cx88 driver, listed below, will gain these init and sleep sequences. CX88_BOARD_HAUPPAUGE_HVR1100 Hauppauge WinTV-HVR1100 DVB-T/Hybrid CX88_BOARD_HAUPPAUGE_HVR1100LP Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profi CX88_BOARD_WINFAST_DTV2000H WinFast DTV2000 H CX88_BOARD_HAUPPAUGE_HVR3000 Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DV CX88_BOARD_HAUPPAUGE_HVR1300 Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encod This non-dvb-pll user in the cx88 driver should only gain the sleep sequence, as it already had an equivalent init sequence. The non-dvb-pll code for this user is removed. X88_BOARD_DNTV_LIVE_DVB_T_PRO digitalnow DNTV Live! DVB-T Pro In these saa7134 driver, these non-dvb-pll users are converted to use dvb-pll: SAA7134_BOARD_MD7134 Medion 7134 SAA7134_BOARD_ASUS_EUROPA2_HYBRID Asus Europa2 OEM The saa7134 functions philips_fmd1216_tuner_init(), philips_fmd1216_tuner_sleep(), and philips_fmd1216_tuner_set_params() are deleted and the dvb-pll versions are used. This should result in equivalent sleep, init, and tuning sequences being sent to the tuner. Signed-off-by: Trent Piepho <xyzzy@xxxxxxxxxxxxx> diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.c b/linux/drivers/media/dvb/frontends/dvb-pll.c --- a/linux/drivers/media/dvb/frontends/dvb-pll.c +++ b/linux/drivers/media/dvb/frontends/dvb-pll.c @@ -38,6 +38,12 @@ 0x50 = AGC Take over point = 103 dBuV */ static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 }; +/* 0x04 = 166.67 kHz divider + + 0x80 = AGC Time constant 50ms Iagc = 9 uA + 0x20 = AGC Take over point = 112 dBuV */ +static u8 tua603x_agc112[] = { 2, 0x80|0x40|0x18|0x04|0x01, 0x80|0x20 }; + struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { .name = "Thomson dtt7579", .min = 177000000, @@ -282,6 +288,8 @@ struct dvb_pll_desc dvb_pll_fmd1216me = .max = 858000000, .iffreq= 36125000, .setbw = fmd1216me_bw, + .initdata = tua603x_agc112, + .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, .count = 7, .entries = { { 143870000, 166667, 0xbc, 0x41 }, diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c --- a/linux/drivers/media/video/cx88/cx88-dvb.c +++ b/linux/drivers/media/video/cx88/cx88-dvb.c @@ -224,64 +224,6 @@ static int dntv_live_dvbt_pro_demod_init return 0; } -static int philips_fmd1216_pll_init(struct dvb_frontend *fe) -{ - struct cx8802_dev *dev= fe->dvb->priv; - - /* this message is to set up ATC and ALC */ - static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; - struct i2c_msg msg = - { .addr = dev->core->pll_addr, .flags = 0, - .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; - int err; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - return 0; -} - -static int dntv_live_dvbt_pro_tuner_set_params(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params) -{ - struct cx8802_dev *dev= fe->dvb->priv; - u8 buf[4]; - struct i2c_msg msg = - { .addr = dev->core->pll_addr, .flags = 0, - .buf = buf, .len = 4 }; - int err; - - /* Switch PLL to DVB mode */ - err = philips_fmd1216_pll_init(fe); - if (err) - return err; - - /* Tune PLL */ - dvb_pll_configure(dev->core->pll_desc, buf, - params->frequency, - params->u.ofdm.bandwidth); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { - - printk(KERN_WARNING "cx88-dvb: %s error " - "(addr %02x <- %02x, err = %i)\n", - __FUNCTION__, dev->core->pll_addr, buf[0], err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - return 0; -} - static struct mt352_config dntv_live_dvbt_pro_config = { .demod_address = 0x0f, .no_tuner = 1, @@ -546,12 +488,11 @@ static int dvb_register(struct cx8802_de break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: #if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) - dev->core->pll_addr = 0x61; - dev->core->pll_desc = &dvb_pll_fmd1216me; dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, &((struct vp3054_i2c_state *)dev->card_priv)->adap); if (dev->dvb.frontend != NULL) { - dev->dvb.frontend->ops.tuner_ops.set_params = dntv_live_dvbt_pro_tuner_set_params; + dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, + &dev->core->i2c_adap, &dvb_pll_fmd1216me); } #else printk("%s: built without vp3054 support\n", dev->core->name); diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c --- a/linux/drivers/media/video/saa7134/saa7134-dvb.c +++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c @@ -445,135 +445,6 @@ static struct tda1004x_config philips_eu /* ------------------------------------------------------------------ */ -static int philips_fmd1216_tuner_init(struct dvb_frontend *fe) -{ - struct saa7134_dev *dev = fe->dvb->priv; - struct tda1004x_state *state = fe->demodulator_priv; - u8 addr = state->config->tuner_address; - /* this message is to set up ATC and ALC */ - static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; - struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - msleep(1); - - return 0; -} - -static int philips_fmd1216_tuner_sleep(struct dvb_frontend *fe) -{ - struct saa7134_dev *dev = fe->dvb->priv; - struct tda1004x_state *state = fe->demodulator_priv; - u8 addr = state->config->tuner_address; - /* this message actually turns the tuner back to analog mode */ - u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 }; - struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); - msleep(1); - fmd1216_init[2] = 0x86; - fmd1216_init[3] = 0x54; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); - msleep(1); - return 0; -} - -static int philips_fmd1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct saa7134_dev *dev = fe->dvb->priv; - struct tda1004x_state *state = fe->demodulator_priv; - u8 addr = state->config->tuner_address; - u8 tuner_buf[4]; - struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len = - sizeof(tuner_buf) }; - int tuner_frequency = 0; - int divider = 0; - u8 band, mode, cp; - - /* determine charge pump */ - tuner_frequency = params->frequency + 36130000; - if (tuner_frequency < 87000000) - return -EINVAL; - /* low band */ - else if (tuner_frequency < 180000000) { - band = 1; - mode = 7; - cp = 0; - } else if (tuner_frequency < 195000000) { - band = 1; - mode = 6; - cp = 1; - /* mid band */ - } else if (tuner_frequency < 366000000) { - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { - band = 10; - } else { - band = 2; - } - mode = 7; - cp = 0; - } else if (tuner_frequency < 478000000) { - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { - band = 10; - } else { - band = 2; - } - mode = 6; - cp = 1; - /* high band */ - } else if (tuner_frequency < 662000000) { - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { - band = 12; - } else { - band = 4; - } - mode = 7; - cp = 0; - } else if (tuner_frequency < 840000000) { - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { - band = 12; - } else { - band = 4; - } - mode = 6; - cp = 1; - } else { - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { - band = 12; - } else { - band = 4; - } - mode = 7; - cp = 1; - - } - /* calculate divisor */ - /* ((36166000 + Finput) / 166666) rounded! */ - divider = (tuner_frequency + 83333) / 166667; - - /* setup tuner buffer */ - tuner_buf[0] = (divider >> 8) & 0x7f; - tuner_buf[1] = divider & 0xff; - tuner_buf[2] = 0x80 | (cp << 6) | (mode << 3) | 4; - tuner_buf[3] = 0x40 | band; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) { - wprintk("could not write to tuner at addr: 0x%02x\n", - addr << 1); - return -EIO; - } - return 0; -} - static struct tda1004x_config medion_cardbus = { .demod_address = 0x08, .invert = 1, @@ -1000,9 +871,8 @@ static int dvb_init(struct saa7134_dev * &medion_cardbus, &dev->i2c_adap); if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = philips_fmd1216_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = philips_fmd1216_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_fmd1216_tuner_set_params; + dvb_attach(dvb_pll_attach, dev->dvb.frontend, medion_cardbus.tuner_address, + &dev->i2c_adap, &dvb_pll_fmd1216me); } break; case SAA7134_BOARD_PHILIPS_TOUGH: @@ -1128,9 +998,9 @@ static int dvb_init(struct saa7134_dev * if (dev->dvb.frontend) { dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; - dev->dvb.frontend->ops.tuner_ops.init = philips_fmd1216_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = philips_fmd1216_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_fmd1216_tuner_set_params; + + dvb_attach(dvb_pll_attach, dev->dvb.frontend, medion_cardbus.tuner_address, + &dev->i2c_adap, &dvb_pll_fmd1216me); } break; case SAA7134_BOARD_VIDEOMATE_DVBT_200A: _______________________________________________ linux-dvb mailing list linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb