diff options
Diffstat (limited to 'drivers/media/tuners')
-rw-r--r-- | drivers/media/tuners/mt2063.c | 44 | ||||
-rw-r--r-- | drivers/media/tuners/mt2063.h | 4 | ||||
-rw-r--r-- | drivers/media/tuners/tda18271-common.c | 104 |
3 files changed, 91 insertions, 61 deletions
diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c index 0ed9091ff48e..2e1a02e360ff 100644 --- a/drivers/media/tuners/mt2063.c +++ b/drivers/media/tuners/mt2063.c @@ -245,7 +245,7 @@ struct mt2063_state { /* * mt2063_write - Write data into the I2C bus */ -static u32 mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len) +static int mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len) { struct dvb_frontend *fe = state->frontend; int ret; @@ -277,9 +277,9 @@ static u32 mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len) /* * mt2063_write - Write register data into the I2C bus, caching the value */ -static u32 mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val) +static int mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val) { - u32 status; + int status; dprintk(2, "\n"); @@ -298,10 +298,10 @@ static u32 mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val) /* * mt2063_read - Read data from the I2C bus */ -static u32 mt2063_read(struct mt2063_state *state, +static int mt2063_read(struct mt2063_state *state, u8 subAddress, u8 *pData, u32 cnt) { - u32 status = 0; /* Status to be returned */ + int status = 0; /* Status to be returned */ struct dvb_frontend *fe = state->frontend; u32 i = 0; @@ -816,7 +816,7 @@ static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info, */ static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info) { - u32 status = 0; + int status = 0; u32 fm, fp; /* restricted range on LO's */ pAS_Info->bSpurAvoided = 0; pAS_Info->nSpursFound = 0; @@ -935,14 +935,14 @@ static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info) * * This function returns 0, if no lock, 1 if locked and a value < 1 if error */ -static unsigned int mt2063_lockStatus(struct mt2063_state *state) +static int mt2063_lockStatus(struct mt2063_state *state) { const u32 nMaxWait = 100; /* wait a maximum of 100 msec */ const u32 nPollRate = 2; /* poll status bits every 2 ms */ const u32 nMaxLoops = nMaxWait / nPollRate; const u8 LO1LK = 0x80; u8 LO2LK = 0x08; - u32 status; + int status; u32 nDelays = 0; dprintk(2, "\n"); @@ -1069,7 +1069,7 @@ static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state, static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state, enum MT2063_DNC_Output_Enable nValue) { - u32 status = 0; /* Status to be returned */ + int status = 0; /* Status to be returned */ u8 val = 0; dprintk(2, "\n"); @@ -1203,7 +1203,7 @@ static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state, static u32 MT2063_SetReceiverMode(struct mt2063_state *state, enum mt2063_delivery_sys Mode) { - u32 status = 0; /* Status to be returned */ + int status = 0; /* Status to be returned */ u8 val; u32 longval; @@ -1345,7 +1345,7 @@ static u32 MT2063_SetReceiverMode(struct mt2063_state *state, static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state, enum MT2063_Mask_Bits Bits) { - u32 status = 0; + int status = 0; dprintk(2, "\n"); Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ @@ -1374,7 +1374,7 @@ static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state, */ static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown) { - u32 status; + int status; dprintk(2, "\n"); if (Shutdown == 1) @@ -1540,7 +1540,7 @@ static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in) static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in) { /* RF input center frequency */ - u32 status = 0; + int status = 0; u32 LO1; /* 1st LO register value */ u32 Num1; /* Numerator for LO1 reg. value */ u32 f_IF1; /* 1st IF requested */ @@ -1803,7 +1803,7 @@ static const u8 MT2063B3_defaults[] = { static int mt2063_init(struct dvb_frontend *fe) { - u32 status; + int status; struct mt2063_state *state = fe->tuner_priv; u8 all_resets = 0xF0; /* reset/load bits */ const u8 *def = NULL; @@ -2249,8 +2249,8 @@ struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, dprintk(2, "\n"); state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL); - if (state == NULL) - goto error; + if (!state) + return NULL; state->config = config; state->i2c = i2c; @@ -2261,18 +2261,15 @@ struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, printk(KERN_INFO "%s: Attaching MT2063\n", __func__); return fe; - -error: - kfree(state); - return NULL; } EXPORT_SYMBOL_GPL(mt2063_attach); +#if 0 /* * Ancillary routines visible outside mt2063 * FIXME: Remove them in favor of using standard tuner callbacks */ -unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe) +static int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe) { struct mt2063_state *state = fe->tuner_priv; int err = 0; @@ -2285,9 +2282,8 @@ unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe) return err; } -EXPORT_SYMBOL_GPL(tuner_MT2063_SoftwareShutdown); -unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe) +static int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe) { struct mt2063_state *state = fe->tuner_priv; int err = 0; @@ -2300,7 +2296,7 @@ unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe) return err; } -EXPORT_SYMBOL_GPL(tuner_MT2063_ClearPowerMaskBits); +#endif MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); MODULE_DESCRIPTION("MT2063 Silicon tuner"); diff --git a/drivers/media/tuners/mt2063.h b/drivers/media/tuners/mt2063.h index 3f5cfd93713f..ab24170c1571 100644 --- a/drivers/media/tuners/mt2063.h +++ b/drivers/media/tuners/mt2063.h @@ -23,10 +23,6 @@ static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, return NULL; } -/* FIXME: Should use the standard DVB attachment interfaces */ -unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe); -unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe); - #endif /* CONFIG_DVB_MT2063 */ #endif /* __MT2063_H__ */ diff --git a/drivers/media/tuners/tda18271-common.c b/drivers/media/tuners/tda18271-common.c index 221171eeb0c3..18c77afe2e4f 100644 --- a/drivers/media/tuners/tda18271-common.c +++ b/drivers/media/tuners/tda18271-common.c @@ -187,7 +187,8 @@ int tda18271_read_extended(struct dvb_frontend *fe) return (ret == 2 ? 0 : ret); } -int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) +static int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len, + bool lock_i2c) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; @@ -198,7 +199,6 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) BUG_ON((len == 0) || (idx + len > sizeof(buf))); - switch (priv->small_i2c) { case TDA18271_03_BYTE_CHUNK_INIT: max = 3; @@ -214,7 +214,19 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) max = 39; } - tda18271_i2c_gate_ctrl(fe, 1); + + /* + * If lock_i2c is true, it will take the I2C bus for tda18271 private + * usage during the entire write ops, as otherwise, bad things could + * happen. + * During device init, several write operations will happen. So, + * tda18271_init_regs controls the I2C lock directly, + * disabling lock_i2c here. + */ + if (lock_i2c) { + tda18271_i2c_gate_ctrl(fe, 1); + i2c_lock_adapter(priv->i2c_props.adap); + } while (len) { if (max > len) max = len; @@ -226,14 +238,17 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) msg.len = max + 1; /* write registers */ - ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); + ret = __i2c_transfer(priv->i2c_props.adap, &msg, 1); if (ret != 1) break; idx += max; len -= max; } - tda18271_i2c_gate_ctrl(fe, 0); + if (lock_i2c) { + i2c_unlock_adapter(priv->i2c_props.adap); + tda18271_i2c_gate_ctrl(fe, 0); + } if (ret != 1) tda_err("ERROR: idx = 0x%x, len = %d, " @@ -242,10 +257,16 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) return (ret == 1 ? 0 : ret); } +int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) +{ + return __tda18271_write_regs(fe, idx, len, true); +} + /*---------------------------------------------------------------------*/ -int tda18271_charge_pump_source(struct dvb_frontend *fe, - enum tda18271_pll pll, int force) +static int __tda18271_charge_pump_source(struct dvb_frontend *fe, + enum tda18271_pll pll, int force, + bool lock_i2c) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; @@ -255,9 +276,16 @@ int tda18271_charge_pump_source(struct dvb_frontend *fe, regs[r_cp] &= ~0x20; regs[r_cp] |= ((force & 1) << 5); - return tda18271_write_regs(fe, r_cp, 1); + return __tda18271_write_regs(fe, r_cp, 1, lock_i2c); +} + +int tda18271_charge_pump_source(struct dvb_frontend *fe, + enum tda18271_pll pll, int force) +{ + return __tda18271_charge_pump_source(fe, pll, force, true); } + int tda18271_init_regs(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; @@ -267,6 +295,13 @@ int tda18271_init_regs(struct dvb_frontend *fe) i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr); + /* + * Don't let any other I2C transfer to happen at adapter during init, + * as those could cause bad things + */ + tda18271_i2c_gate_ctrl(fe, 1); + i2c_lock_adapter(priv->i2c_props.adap); + /* initialize registers */ switch (priv->id) { case TDA18271HDC1: @@ -352,28 +387,28 @@ int tda18271_init_regs(struct dvb_frontend *fe) regs[R_EB22] = 0x48; regs[R_EB23] = 0xb0; - tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS); + __tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS, false); /* setup agc1 gain */ regs[R_EB17] = 0x00; - tda18271_write_regs(fe, R_EB17, 1); + __tda18271_write_regs(fe, R_EB17, 1, false); regs[R_EB17] = 0x03; - tda18271_write_regs(fe, R_EB17, 1); + __tda18271_write_regs(fe, R_EB17, 1, false); regs[R_EB17] = 0x43; - tda18271_write_regs(fe, R_EB17, 1); + __tda18271_write_regs(fe, R_EB17, 1, false); regs[R_EB17] = 0x4c; - tda18271_write_regs(fe, R_EB17, 1); + __tda18271_write_regs(fe, R_EB17, 1, false); /* setup agc2 gain */ if ((priv->id) == TDA18271HDC1) { regs[R_EB20] = 0xa0; - tda18271_write_regs(fe, R_EB20, 1); + __tda18271_write_regs(fe, R_EB20, 1, false); regs[R_EB20] = 0xa7; - tda18271_write_regs(fe, R_EB20, 1); + __tda18271_write_regs(fe, R_EB20, 1, false); regs[R_EB20] = 0xe7; - tda18271_write_regs(fe, R_EB20, 1); + __tda18271_write_regs(fe, R_EB20, 1, false); regs[R_EB20] = 0xec; - tda18271_write_regs(fe, R_EB20, 1); + __tda18271_write_regs(fe, R_EB20, 1, false); } /* image rejection calibration */ @@ -391,21 +426,21 @@ int tda18271_init_regs(struct dvb_frontend *fe) regs[R_MD2] = 0x08; regs[R_MD3] = 0x00; - tda18271_write_regs(fe, R_EP3, 11); + __tda18271_write_regs(fe, R_EP3, 11, false); if ((priv->id) == TDA18271HDC2) { /* main pll cp source on */ - tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1); + __tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1, false); msleep(1); /* main pll cp source off */ - tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0); + __tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0, false); } msleep(5); /* pll locking */ /* launch detector */ - tda18271_write_regs(fe, R_EP1, 1); + __tda18271_write_regs(fe, R_EP1, 1, false); msleep(5); /* wanted low measurement */ regs[R_EP5] = 0x85; @@ -413,11 +448,11 @@ int tda18271_init_regs(struct dvb_frontend *fe) regs[R_CD1] = 0x66; regs[R_CD2] = 0x70; - tda18271_write_regs(fe, R_EP3, 7); + __tda18271_write_regs(fe, R_EP3, 7, false); msleep(5); /* pll locking */ /* launch optimization algorithm */ - tda18271_write_regs(fe, R_EP2, 1); + __tda18271_write_regs(fe, R_EP2, 1, false); msleep(30); /* image low optimization completion */ /* mid-band */ @@ -428,11 +463,11 @@ int tda18271_init_regs(struct dvb_frontend *fe) regs[R_MD1] = 0x73; regs[R_MD2] = 0x1a; - tda18271_write_regs(fe, R_EP3, 11); + __tda18271_write_regs(fe, R_EP3, 11, false); msleep(5); /* pll locking */ /* launch detector */ - tda18271_write_regs(fe, R_EP1, 1); + __tda18271_write_regs(fe, R_EP1, 1, false); msleep(5); /* wanted mid measurement */ regs[R_EP5] = 0x86; @@ -440,11 +475,11 @@ int tda18271_init_regs(struct dvb_frontend *fe) regs[R_CD1] = 0x66; regs[R_CD2] = 0xa0; - tda18271_write_regs(fe, R_EP3, 7); + __tda18271_write_regs(fe, R_EP3, 7, false); msleep(5); /* pll locking */ /* launch optimization algorithm */ - tda18271_write_regs(fe, R_EP2, 1); + __tda18271_write_regs(fe, R_EP2, 1, false); msleep(30); /* image mid optimization completion */ /* high-band */ @@ -456,30 +491,33 @@ int tda18271_init_regs(struct dvb_frontend *fe) regs[R_MD1] = 0x71; regs[R_MD2] = 0xcd; - tda18271_write_regs(fe, R_EP3, 11); + __tda18271_write_regs(fe, R_EP3, 11, false); msleep(5); /* pll locking */ /* launch detector */ - tda18271_write_regs(fe, R_EP1, 1); + __tda18271_write_regs(fe, R_EP1, 1, false); msleep(5); /* wanted high measurement */ regs[R_EP5] = 0x87; regs[R_CD1] = 0x65; regs[R_CD2] = 0x50; - tda18271_write_regs(fe, R_EP3, 7); + __tda18271_write_regs(fe, R_EP3, 7, false); msleep(5); /* pll locking */ /* launch optimization algorithm */ - tda18271_write_regs(fe, R_EP2, 1); + __tda18271_write_regs(fe, R_EP2, 1, false); msleep(30); /* image high optimization completion */ /* return to normal mode */ regs[R_EP4] = 0x64; - tda18271_write_regs(fe, R_EP4, 1); + __tda18271_write_regs(fe, R_EP4, 1, false); /* synchronize */ - tda18271_write_regs(fe, R_EP1, 1); + __tda18271_write_regs(fe, R_EP1, 1, false); + + i2c_unlock_adapter(priv->i2c_props.adap); + tda18271_i2c_gate_ctrl(fe, 0); return 0; } |