diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 3ec76391a60d..3a27d4a8ce38 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c @@ -810,6 +810,52 @@ static int simple_dvb_set_params(struct dvb_frontend *fe, return ret; } +static int simple_init(struct dvb_frontend *fe) +{ + struct tuner_simple_priv *priv = fe->tuner_priv; + + if (priv->i2c_props.adap == NULL) + return -EINVAL; + + if (priv->tun->initdata) { + int ret; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = tuner_i2c_xfer_send(&priv->i2c_props, + priv->tun->initdata + 1, + priv->tun->initdata[0]); + if (ret != priv->tun->initdata[0]) + return ret; + } + + return 0; +} + +static int simple_sleep(struct dvb_frontend *fe) +{ + struct tuner_simple_priv *priv = fe->tuner_priv; + + if (priv->i2c_props.adap == NULL) + return -EINVAL; + + if (priv->tun->sleepdata) { + int ret; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = tuner_i2c_xfer_send(&priv->i2c_props, + priv->tun->sleepdata + 1, + priv->tun->sleepdata[0]); + if (ret != priv->tun->sleepdata[0]) + return ret; + } + + return 0; +} + static int simple_release(struct dvb_frontend *fe) { struct tuner_simple_priv *priv = fe->tuner_priv; @@ -841,6 +887,8 @@ static int simple_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) } static struct dvb_tuner_ops simple_tuner_ops = { + .init = simple_init, + .sleep = simple_sleep, .set_analog_params = simple_set_params, .set_params = simple_dvb_set_params, .calc_regs = simple_dvb_calc_regs, diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index 8b53d0d05b23..13c76a57d8e2 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c @@ -35,6 +35,27 @@ * based on the video standard in use. */ +/* The following was taken from dvb-pll.c: */ + +/* Set AGC TOP value to 103 dBuV: + * 0x80 = Control Byte + * 0x40 = 250 uA charge pump (irrelevant) + * 0x18 = Aux Byte to follow + * 0x06 = 64.5 kHz divider (irrelevant) + * 0x01 = Disable Vt (aka sleep) + * + * 0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA) + * 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 }; + /* 0-9 */ /* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */ @@ -1425,6 +1446,7 @@ struct tunertype tuners[] = { .min = 16 * 57.00, .max = 16 * 863.00, .stepsize = 62500, + .initdata = tua603x_agc103, }, [TUNER_TENA_9533_DI] = { /* Philips PAL */ .name = "Tena TNF9533-D/IF/TNF9533-B/DF", @@ -1439,6 +1461,8 @@ struct tunertype tuners[] = { .name = "Philips FMD1216ME MK3 Hybrid Tuner", .params = tuner_philips_fmd1216me_mk3_params, .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params), + .initdata = tua603x_agc112, + .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, }, [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */ .name = "LG TDVS-H06xF", /* H061F, H062F & H064F */ @@ -1447,6 +1471,7 @@ struct tunertype tuners[] = { .min = 16 * 54.00, .max = 16 * 863.00, .stepsize = 62500, + .initdata = tua603x_agc103, }, [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ .name = "Ymec TVF66T5-B/DFF", diff --git a/include/media/tuner-types.h b/include/media/tuner-types.h index 4b5e5cf780c8..fda12093cab3 100644 --- a/include/media/tuner-types.h +++ b/include/media/tuner-types.h @@ -120,6 +120,9 @@ struct tunertype { u16 min; u16 max; u16 stepsize; + + u8 *initdata; + u8 *sleepdata; }; extern struct tunertype tuners[];