diff options
Diffstat (limited to 'linux/drivers/media/common')
-rw-r--r-- | linux/drivers/media/common/tuners/tda18271-common.c | 3 | ||||
-rw-r--r-- | linux/drivers/media/common/tuners/tda18271-fe.c | 103 | ||||
-rw-r--r-- | linux/drivers/media/common/tuners/tda18271-maps.c | 3 | ||||
-rw-r--r-- | linux/drivers/media/common/tuners/tda18271-priv.h | 21 | ||||
-rw-r--r-- | linux/drivers/media/common/tuners/tda18271.h | 17 |
5 files changed, 106 insertions, 41 deletions
diff --git a/linux/drivers/media/common/tuners/tda18271-common.c b/linux/drivers/media/common/tuners/tda18271-common.c index a49facb7b..4092bcf01 100644 --- a/linux/drivers/media/common/tuners/tda18271-common.c +++ b/linux/drivers/media/common/tuners/tda18271-common.c @@ -210,7 +210,8 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) tda18271_i2c_gate_ctrl(fe, 0); if (ret != 1) - tda_err("ERROR: i2c_transfer returned: %d\n", ret); + tda_err("ERROR: idx = 0x%x, len = %d, " + "i2c_transfer returned: %d\n", idx, len, ret); return (ret == 1 ? 0 : ret); } diff --git a/linux/drivers/media/common/tuners/tda18271-fe.c b/linux/drivers/media/common/tuners/tda18271-fe.c index 85e30af31..a3e122c89 100644 --- a/linux/drivers/media/common/tuners/tda18271-fe.c +++ b/linux/drivers/media/common/tuners/tda18271-fe.c @@ -28,7 +28,7 @@ module_param_named(debug, tda18271_debug, int, 0644); MODULE_PARM_DESC(debug, "set debug level " "(info=1, map=2, reg=4, adv=8, cal=16 (or-able))"); -static int tda18271_cal_on_startup; +static int tda18271_cal_on_startup = -1; module_param_named(cal, tda18271_cal_on_startup, int, 0644); MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup"); @@ -37,6 +37,27 @@ static LIST_HEAD(hybrid_tuner_instance_list); /*---------------------------------------------------------------------*/ +static int tda18271_toggle_output(struct dvb_frontend *fe, int standby) +{ + struct tda18271_priv *priv = fe->tuner_priv; + + int ret = tda18271_set_standby_mode(fe, standby ? 1 : 0, + priv->output_opt & TDA18271_OUTPUT_LT_OFF ? 1 : 0, + priv->output_opt & TDA18271_OUTPUT_XT_OFF ? 1 : 0); + + if (tda_fail(ret)) + goto fail; + + tda_dbg("%s mode: xtal oscillator %s, slave tuner loop thru %s\n", + standby ? "standby" : "active", + priv->output_opt & TDA18271_OUTPUT_XT_OFF ? "off" : "on", + priv->output_opt & TDA18271_OUTPUT_LT_OFF ? "off" : "on"); +fail: + return ret; +} + +/*---------------------------------------------------------------------*/ + static inline int charge_pump_source(struct dvb_frontend *fe, int force) { struct tda18271_priv *priv = fe->tuner_priv; @@ -272,7 +293,7 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe, tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt); /* calculate temperature compensation */ - rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal); + rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000; regs[R_EB14] = approx + rfcal_comp; ret = tda18271_write_regs(fe, R_EB14, 1); @@ -801,7 +822,7 @@ static int tda18271_init(struct dvb_frontend *fe) mutex_lock(&priv->lock); - /* power up */ + /* full power up */ ret = tda18271_set_standby_mode(fe, 0, 0, 0); if (tda_fail(ret)) goto fail; @@ -819,6 +840,21 @@ fail: return ret; } +static int tda18271_sleep(struct dvb_frontend *fe) +{ + struct tda18271_priv *priv = fe->tuner_priv; + int ret; + + mutex_lock(&priv->lock); + + /* enter standby mode, with required output features enabled */ + ret = tda18271_toggle_output(fe, 1); + + mutex_unlock(&priv->lock); + + return ret; +} + /* ------------------------------------------------------------------ */ static int tda18271_agc(struct dvb_frontend *fe) @@ -828,8 +864,9 @@ static int tda18271_agc(struct dvb_frontend *fe) switch (priv->config) { case 0: - /* no LNA */ - tda_dbg("no agc configuration provided\n"); + /* no external agc configuration required */ + if (tda18271_debug & DBG_ADV) + tda_dbg("no agc configuration provided\n"); break; case 3: /* switch with GPIO of saa713x */ @@ -1011,22 +1048,6 @@ fail: return ret; } -static int tda18271_sleep(struct dvb_frontend *fe) -{ - struct tda18271_priv *priv = fe->tuner_priv; - int ret; - - mutex_lock(&priv->lock); - - /* standby mode w/ slave tuner output - * & loop thru & xtal oscillator on */ - ret = tda18271_set_standby_mode(fe, 1, 0, 0); - - mutex_unlock(&priv->lock); - - return ret; -} - static int tda18271_release(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; @@ -1193,18 +1214,33 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, case 0: goto fail; case 1: + { /* new tuner instance */ + int rf_cal_on_startup; + priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; priv->role = (cfg) ? cfg->role : TDA18271_MASTER; priv->config = (cfg) ? cfg->config : 0; + priv->small_i2c = (cfg) ? cfg->small_i2c : 0; + priv->output_opt = (cfg) ? + cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON; + + /* tda18271_cal_on_startup == -1 when cal + * module option is unset */ + if (tda18271_cal_on_startup == -1) { + /* honor attach-time configuration */ + rf_cal_on_startup = + ((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0; + } else { + /* module option overrides attach configuration */ + rf_cal_on_startup = tda18271_cal_on_startup; + } + priv->cal_initialized = false; mutex_init(&priv->lock); fe->tuner_priv = priv; - if (cfg) - priv->small_i2c = cfg->small_i2c; - if (tda_fail(tda18271_get_id(fe))) goto fail; @@ -1214,18 +1250,29 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, mutex_lock(&priv->lock); tda18271_init_regs(fe); - if ((tda18271_cal_on_startup) && (priv->id == TDA18271HDC2)) + if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2)) tda18271c2_rf_cal_init(fe); mutex_unlock(&priv->lock); break; + } default: /* existing tuner instance */ fe->tuner_priv = priv; - /* allow dvb driver to override i2c gate setting */ - if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG)) - priv->gate = cfg->gate; + /* allow dvb driver to override configuration settings */ + if (cfg) { + if (cfg->gate != TDA18271_GATE_ANALOG) + priv->gate = cfg->gate; + if (cfg->role) + priv->role = cfg->role; + if (cfg->config) + priv->config = cfg->config; + if (cfg->small_i2c) + priv->small_i2c = cfg->small_i2c; + if (cfg->output_opt) + priv->output_opt = cfg->output_opt; + } break; } diff --git a/linux/drivers/media/common/tuners/tda18271-maps.c b/linux/drivers/media/common/tuners/tda18271-maps.c index ab14ceb9e..e21fdeff3 100644 --- a/linux/drivers/media/common/tuners/tda18271-maps.c +++ b/linux/drivers/media/common/tuners/tda18271-maps.c @@ -962,10 +962,9 @@ struct tda18271_cid_target_map { static struct tda18271_cid_target_map tda18271_cid_target[] = { { .rfmax = 46000, .target = 0x04, .limit = 1800 }, { .rfmax = 52200, .target = 0x0a, .limit = 1500 }, - { .rfmax = 79100, .target = 0x01, .limit = 4000 }, + { .rfmax = 70100, .target = 0x01, .limit = 4000 }, { .rfmax = 136800, .target = 0x18, .limit = 4000 }, { .rfmax = 156700, .target = 0x18, .limit = 4000 }, - { .rfmax = 156700, .target = 0x18, .limit = 4000 }, { .rfmax = 186250, .target = 0x0a, .limit = 4000 }, { .rfmax = 230000, .target = 0x0a, .limit = 4000 }, { .rfmax = 345000, .target = 0x18, .limit = 4000 }, diff --git a/linux/drivers/media/common/tuners/tda18271-priv.h b/linux/drivers/media/common/tuners/tda18271-priv.h index f3adbb212..11dbc0b33 100644 --- a/linux/drivers/media/common/tuners/tda18271-priv.h +++ b/linux/drivers/media/common/tuners/tda18271-priv.h @@ -109,6 +109,7 @@ struct tda18271_priv { enum tda18271_role role; enum tda18271_i2c_gate gate; enum tda18271_ver id; + enum tda18271_output_options output_opt; unsigned int config; /* interface to saa713x / tda829x */ unsigned int tm_rfcal; @@ -138,17 +139,17 @@ extern int tda18271_debug; #define tda_printk(kern, fmt, arg...) \ printk(kern "%s: " fmt, __func__, ##arg) -#define dprintk(kern, lvl, fmt, arg...) do {\ +#define tda_dprintk(lvl, fmt, arg...) do {\ if (tda18271_debug & lvl) \ - tda_printk(kern, fmt, ##arg); } while (0) - -#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg) -#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg) -#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg) -#define tda_dbg(fmt, arg...) dprintk(KERN_DEBUG, DBG_INFO, fmt, ##arg) -#define tda_map(fmt, arg...) dprintk(KERN_DEBUG, DBG_MAP, fmt, ##arg) -#define tda_reg(fmt, arg...) dprintk(KERN_DEBUG, DBG_REG, fmt, ##arg) -#define tda_cal(fmt, arg...) dprintk(KERN_DEBUG, DBG_CAL, fmt, ##arg) + tda_printk(KERN_DEBUG, fmt, ##arg); } while (0) + +#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg) +#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg) +#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg) +#define tda_dbg(fmt, arg...) tda_dprintk(DBG_INFO, fmt, ##arg) +#define tda_map(fmt, arg...) tda_dprintk(DBG_MAP, fmt, ##arg) +#define tda_reg(fmt, arg...) tda_dprintk(DBG_REG, fmt, ##arg) +#define tda_cal(fmt, arg...) tda_dprintk(DBG_CAL, fmt, ##arg) #define tda_fail(ret) \ ({ \ diff --git a/linux/drivers/media/common/tuners/tda18271.h b/linux/drivers/media/common/tuners/tda18271.h index 53a9892a1..323f29121 100644 --- a/linux/drivers/media/common/tuners/tda18271.h +++ b/linux/drivers/media/common/tuners/tda18271.h @@ -67,6 +67,17 @@ enum tda18271_i2c_gate { TDA18271_GATE_DIGITAL, }; +enum tda18271_output_options { + /* slave tuner output & loop thru & xtal oscillator always on */ + TDA18271_OUTPUT_LT_XT_ON = 0, + + /* slave tuner output loop thru off */ + TDA18271_OUTPUT_LT_OFF = 1, + + /* xtal oscillator off */ + TDA18271_OUTPUT_XT_OFF = 2, +}; + struct tda18271_config { /* override default if freq / std settings (optional) */ struct tda18271_std_map *std_map; @@ -77,6 +88,12 @@ struct tda18271_config { /* use i2c gate provided by analog or digital demod */ enum tda18271_i2c_gate gate; + /* output options that can be disabled */ + enum tda18271_output_options output_opt; + + /* force rf tracking filter calibration on startup */ + unsigned int rf_cal_on_startup:1; + /* some i2c providers cant write all 39 registers at once */ unsigned int small_i2c:1; |