X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fdvb%2Ffrontends%2Ftda1004x.c;h=00e4bcd9f1a4304e5ec99dbaeab0899af9b8de6e;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=8e8df7b4ca0e595f8d28f710a273357ab37da3ad;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index 8e8df7b4c..00e4bcd9f 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -47,12 +47,10 @@ enum tda1004x_demod { struct tda1004x_state { struct i2c_adapter* i2c; - struct dvb_frontend_ops ops; const struct tda1004x_config* config; struct dvb_frontend frontend; /* private demod data */ - u8 initialised; enum tda1004x_demod demod_type; }; @@ -581,11 +579,14 @@ static int tda1004x_decode_fec(int tdafec) return -1; } -int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data) +int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len) { struct tda1004x_state* state = fe->demodulator_priv; - return tda1004x_write_byteI(state, reg, data); + if (len != 2) + return -EINVAL; + + return tda1004x_write_byteI(state, buf[0], buf[1]); } static int tda10045_init(struct dvb_frontend* fe) @@ -594,9 +595,6 @@ static int tda10045_init(struct dvb_frontend* fe) dprintk("%s\n", __FUNCTION__); - if (state->initialised) - return 0; - if (tda10045_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); return -EIO; @@ -604,13 +602,6 @@ static int tda10045_init(struct dvb_frontend* fe) tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC - // Init the PLL - if (state->config->pll_init) { - tda1004x_enable_tuner_i2c(state); - state->config->pll_init(fe); - tda1004x_disable_tuner_i2c(state); - } - // tda setup tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream @@ -626,7 +617,6 @@ static int tda10045_init(struct dvb_frontend* fe) tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk); - state->initialised = 1; return 0; } @@ -635,24 +625,11 @@ static int tda10046_init(struct dvb_frontend* fe) struct tda1004x_state* state = fe->demodulator_priv; dprintk("%s\n", __FUNCTION__); - if (state->initialised) - return 0; - if (tda10046_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); return -EIO; } - // Init the tuner PLL - if (state->config->pll_init) { - tda1004x_enable_tuner_i2c(state); - if (state->config->pll_init(fe)) { - printk(KERN_ERR "tda1004x: pll init failed\n"); - return -EIO; - } - tda1004x_disable_tuner_i2c(state); - } - // tda setup tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream @@ -671,18 +648,24 @@ static int tda10046_init(struct dvb_frontend* fe) tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities break; - case TDA10046_AGC_TDA827X: + case TDA10046_AGC_TDA827X_GP11: tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities break; - case TDA10046_AGC_TDA827X_GPL: + case TDA10046_AGC_TDA827X_GP00: tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities break; + case TDA10046_AGC_TDA827X_GP01: + tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup + tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold + tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize + tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x62); // set AGC polarities + break; } tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on @@ -697,7 +680,6 @@ static int tda10046_init(struct dvb_frontend* fe) // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); - state->initialised = 1; return 0; } @@ -721,12 +703,10 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, } // set frequency - tda1004x_enable_tuner_i2c(state); - if (state->config->pll_set(fe, fe_params)) { - printk(KERN_ERR "tda1004x: pll set failed\n"); - return -EIO; + if (fe->ops.tuner_ops.set_params) { + fe->ops.tuner_ops.set_params(fe, fe_params); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - tda1004x_disable_tuner_i2c(state); // Hardcoded to use auto as much as possible on the TDA10045 as it // is very unreliable if AUTO mode is _not_ used. @@ -1192,26 +1172,26 @@ static int tda1004x_sleep(struct dvb_frontend* fe) break; case TDA1004X_DEMOD_TDA10046: - if (state->config->pll_sleep != NULL) { - tda1004x_enable_tuner_i2c(state); - state->config->pll_sleep(fe); - if (state->config->if_freq != TDA10046_FREQ_052) { - /* special hack for Philips EUROPA Based boards: - * keep the I2c bridge open for tuner access in analog mode - */ - tda1004x_disable_tuner_i2c(state); - } - } /* set outputs to tristate */ tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); break; } - state->initialised = 0; return 0; } +static int tda1004x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) +{ + struct tda1004x_state* state = fe->demodulator_priv; + + if (enable) { + return tda1004x_enable_tuner_i2c(state); + } else { + return tda1004x_disable_tuner_i2c(state); + } +} + static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) { fesettings->min_delay_ms = 800; @@ -1245,6 +1225,8 @@ static struct dvb_frontend_ops tda10045_ops = { .init = tda10045_init, .sleep = tda1004x_sleep, + .write = tda1004x_write, + .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, .set_frontend = tda1004x_set_fe, .get_frontend = tda1004x_get_fe, @@ -1270,8 +1252,6 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, /* setup the state */ state->config = config; state->i2c = i2c; - memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); - state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10045; /* check if the demod is there */ @@ -1281,7 +1261,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, } /* create dvb_frontend */ - state->frontend.ops = &state->ops; + memcpy(&state->frontend.ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; return &state->frontend; } @@ -1304,6 +1284,8 @@ static struct dvb_frontend_ops tda10046_ops = { .init = tda10046_init, .sleep = tda1004x_sleep, + .write = tda1004x_write, + .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, .set_frontend = tda1004x_set_fe, .get_frontend = tda1004x_get_fe, @@ -1329,8 +1311,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, /* setup the state */ state->config = config; state->i2c = i2c; - memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); - state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10046; /* check if the demod is there */ @@ -1340,7 +1320,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, } /* create dvb_frontend */ - state->frontend.ops = &state->ops; + memcpy(&state->frontend.ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; return &state->frontend; } @@ -1354,4 +1334,3 @@ MODULE_LICENSE("GPL"); EXPORT_SYMBOL(tda10045_attach); EXPORT_SYMBOL(tda10046_attach); -EXPORT_SYMBOL(tda1004x_write_byte);