diff --git a/drivers/media/dvb/frontends/tda18271-common.c b/drivers/media/dvb/frontends/tda18271-common.c index d7a335659474..cebb6b90b7e0 100644 --- a/drivers/media/dvb/frontends/tda18271-common.c +++ b/drivers/media/dvb/frontends/tda18271-common.c @@ -452,6 +452,42 @@ int tda18271_init_regs(struct dvb_frontend *fe) /*---------------------------------------------------------------------*/ +/* + * Standby modes, EP3 [7:5] + * + * | SM || SM_LT || SM_XT || mode description + * |=====\\=======\\=======\\=================================== + * | 0 || 0 || 0 || normal mode + * |-----||-------||-------||----------------------------------- + * | || || || standby mode w/ slave tuner output + * | 1 || 0 || 0 || & loop thru & xtal oscillator on + * |-----||-------||-------||----------------------------------- + * | 1 || 1 || 0 || standby mode w/ xtal oscillator on + * |-----||-------||-------||----------------------------------- + * | 1 || 1 || 1 || power off + * + */ + +int tda18271_set_standby_mode(struct dvb_frontend *fe, + int sm, int sm_lt, int sm_xt) +{ + struct tda18271_priv *priv = fe->tuner_priv; + unsigned char *regs = priv->tda18271_regs; + + tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt); + + regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ + regs[R_EP3] |= sm ? (1 << 7) : 0 | + sm_lt ? (1 << 6) : 0 | + sm_xt ? (1 << 5) : 0; + + tda18271_write_regs(fe, R_EP3, 1); + + return 0; +} + +/*---------------------------------------------------------------------*/ + int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq) { /* sets main post divider & divider bytes, but does not write them */ diff --git a/drivers/media/dvb/frontends/tda18271-fe.c b/drivers/media/dvb/frontends/tda18271-fe.c index c254ac367e72..c8ab1fda1dea 100644 --- a/drivers/media/dvb/frontends/tda18271-fe.c +++ b/drivers/media/dvb/frontends/tda18271-fe.c @@ -201,8 +201,7 @@ static int tda18271_rf_tracking_filters_correction(struct dvb_frontend *fe, u8 dc_over_dt, rf_tab; /* power up */ - regs[R_EP3] &= ~0xe0; /* sm = 0, sm_lt = 0, sm_xt = 0 */ - tda18271_write_regs(fe, R_EP3, 1); + tda18271_set_standby_mode(fe, 0, 0, 0); /* read die current temperature */ tm_current = tda18271_read_thermometer(fe); @@ -256,9 +255,7 @@ static int tda18271_por(struct dvb_frontend *fe) regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */ /* POR mode */ - regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ - regs[R_EP3] |= 0x80; /* sm = 1, sm_lt = 0, sm_xt = 0 */ - tda18271_write_regs(fe, R_EP3, 1); + tda18271_set_standby_mode(fe, 1, 0, 0); /* disable 1.5 MHz low pass filter */ regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */ @@ -610,6 +607,9 @@ static int tda18271_init(struct dvb_frontend *fe) mutex_lock(&priv->lock); + /* power up */ + tda18271_set_standby_mode(fe, 0, 0, 0); + /* initialization */ tda18271_ir_cal_init(fe); @@ -953,6 +953,21 @@ fail: return ret; } +static int tda18271_sleep(struct dvb_frontend *fe) +{ + struct tda18271_priv *priv = fe->tuner_priv; + + mutex_lock(&priv->lock); + + /* standby mode w/ slave tuner output + * & loop thru & xtal oscillator on */ + tda18271_set_standby_mode(fe, 1, 0, 0); + + mutex_unlock(&priv->lock); + + return 0; +} + static int tda18271_release(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; @@ -1096,6 +1111,7 @@ static struct dvb_tuner_ops tda18271_tuner_ops = { .frequency_step = 62500 }, .init = tda18271_init, + .sleep = tda18271_sleep, .set_params = tda18271_set_params, .set_analog_params = tda18271_set_analog_params, .release = tda18271_release, diff --git a/drivers/media/dvb/frontends/tda18271-priv.h b/drivers/media/dvb/frontends/tda18271-priv.h index 080efb3991ed..7b939a5325fb 100644 --- a/drivers/media/dvb/frontends/tda18271-priv.h +++ b/drivers/media/dvb/frontends/tda18271-priv.h @@ -188,6 +188,9 @@ extern int tda18271_read_extended(struct dvb_frontend *fe); extern int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len); extern int tda18271_init_regs(struct dvb_frontend *fe); +extern int tda18271_set_standby_mode(struct dvb_frontend *fe, + int sm, int sm_lt, int sm_xt); + extern int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq); extern int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq);