Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * NXP TDA18218HN silicon tuner driver
0004  *
0005  * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
0006  */
0007 
0008 #include "tda18218_priv.h"
0009 
0010 /* Max transfer size done by I2C transfer functions */
0011 #define MAX_XFER_SIZE  64
0012 
0013 /* write multiple registers */
0014 static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
0015 {
0016     int ret = 0, len2, remaining;
0017     u8 buf[MAX_XFER_SIZE];
0018     struct i2c_msg msg[1] = {
0019         {
0020             .addr = priv->cfg->i2c_address,
0021             .flags = 0,
0022             .buf = buf,
0023         }
0024     };
0025 
0026     if (1 + len > sizeof(buf)) {
0027         dev_warn(&priv->i2c->dev,
0028              "%s: i2c wr reg=%04x: len=%d is too big!\n",
0029              KBUILD_MODNAME, reg, len);
0030         return -EINVAL;
0031     }
0032 
0033     for (remaining = len; remaining > 0;
0034             remaining -= (priv->cfg->i2c_wr_max - 1)) {
0035         len2 = remaining;
0036         if (len2 > (priv->cfg->i2c_wr_max - 1))
0037             len2 = (priv->cfg->i2c_wr_max - 1);
0038 
0039         msg[0].len = 1 + len2;
0040         buf[0] = reg + len - remaining;
0041         memcpy(&buf[1], &val[len - remaining], len2);
0042 
0043         ret = i2c_transfer(priv->i2c, msg, 1);
0044         if (ret != 1)
0045             break;
0046     }
0047 
0048     if (ret == 1) {
0049         ret = 0;
0050     } else {
0051         dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
0052                 "len=%d\n", KBUILD_MODNAME, ret, reg, len);
0053         ret = -EREMOTEIO;
0054     }
0055 
0056     return ret;
0057 }
0058 
0059 /* read multiple registers */
0060 static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
0061 {
0062     int ret;
0063     u8 buf[MAX_XFER_SIZE]; /* we must start read always from reg 0x00 */
0064     struct i2c_msg msg[2] = {
0065         {
0066             .addr = priv->cfg->i2c_address,
0067             .flags = 0,
0068             .len = 1,
0069             .buf = "\x00",
0070         }, {
0071             .addr = priv->cfg->i2c_address,
0072             .flags = I2C_M_RD,
0073             .len = reg + len,
0074             .buf = buf,
0075         }
0076     };
0077 
0078     if (reg + len > sizeof(buf)) {
0079         dev_warn(&priv->i2c->dev,
0080              "%s: i2c wr reg=%04x: len=%d is too big!\n",
0081              KBUILD_MODNAME, reg, len);
0082         return -EINVAL;
0083     }
0084 
0085     ret = i2c_transfer(priv->i2c, msg, 2);
0086     if (ret == 2) {
0087         memcpy(val, &buf[reg], len);
0088         ret = 0;
0089     } else {
0090         dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
0091                 "len=%d\n", KBUILD_MODNAME, ret, reg, len);
0092         ret = -EREMOTEIO;
0093     }
0094 
0095     return ret;
0096 }
0097 
0098 /* write single register */
0099 static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val)
0100 {
0101     return tda18218_wr_regs(priv, reg, &val, 1);
0102 }
0103 
0104 /* read single register */
0105 
0106 static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val)
0107 {
0108     return tda18218_rd_regs(priv, reg, val, 1);
0109 }
0110 
0111 static int tda18218_set_params(struct dvb_frontend *fe)
0112 {
0113     struct tda18218_priv *priv = fe->tuner_priv;
0114     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0115     u32 bw = c->bandwidth_hz;
0116     int ret;
0117     u8 buf[3], i, BP_Filter, LP_Fc;
0118     u32 LO_Frac;
0119     /* TODO: find out correct AGC algorithm */
0120     u8 agc[][2] = {
0121         { R20_AGC11, 0x60 },
0122         { R23_AGC21, 0x02 },
0123         { R20_AGC11, 0xa0 },
0124         { R23_AGC21, 0x09 },
0125         { R20_AGC11, 0xe0 },
0126         { R23_AGC21, 0x0c },
0127         { R20_AGC11, 0x40 },
0128         { R23_AGC21, 0x01 },
0129         { R20_AGC11, 0x80 },
0130         { R23_AGC21, 0x08 },
0131         { R20_AGC11, 0xc0 },
0132         { R23_AGC21, 0x0b },
0133         { R24_AGC22, 0x1c },
0134         { R24_AGC22, 0x0c },
0135     };
0136 
0137     if (fe->ops.i2c_gate_ctrl)
0138         fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
0139 
0140     /* low-pass filter cut-off frequency */
0141     if (bw <= 6000000) {
0142         LP_Fc = 0;
0143         priv->if_frequency = 3000000;
0144     } else if (bw <= 7000000) {
0145         LP_Fc = 1;
0146         priv->if_frequency = 3500000;
0147     } else {
0148         LP_Fc = 2;
0149         priv->if_frequency = 4000000;
0150     }
0151 
0152     LO_Frac = c->frequency + priv->if_frequency;
0153 
0154     /* band-pass filter */
0155     if (LO_Frac < 188000000)
0156         BP_Filter = 3;
0157     else if (LO_Frac < 253000000)
0158         BP_Filter = 4;
0159     else if (LO_Frac < 343000000)
0160         BP_Filter = 5;
0161     else
0162         BP_Filter = 6;
0163 
0164     buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */
0165     buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */
0166     buf[2] = priv->regs[R1C_AGC2B];
0167     ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3);
0168     if (ret)
0169         goto error;
0170 
0171     buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */
0172     buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */
0173     buf[2] = (LO_Frac / 1000) << 4 |
0174         (priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */
0175     ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3);
0176     if (ret)
0177         goto error;
0178 
0179     buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */
0180     ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
0181     if (ret)
0182         goto error;
0183 
0184     buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */
0185     ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
0186     if (ret)
0187         goto error;
0188 
0189     /* trigger AGC */
0190     for (i = 0; i < ARRAY_SIZE(agc); i++) {
0191         ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]);
0192         if (ret)
0193             goto error;
0194     }
0195 
0196 error:
0197     if (fe->ops.i2c_gate_ctrl)
0198         fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
0199 
0200     if (ret)
0201         dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
0202 
0203     return ret;
0204 }
0205 
0206 static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
0207 {
0208     struct tda18218_priv *priv = fe->tuner_priv;
0209     *frequency = priv->if_frequency;
0210     dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d\n", __func__, *frequency);
0211     return 0;
0212 }
0213 
0214 static int tda18218_sleep(struct dvb_frontend *fe)
0215 {
0216     struct tda18218_priv *priv = fe->tuner_priv;
0217     int ret;
0218 
0219     if (fe->ops.i2c_gate_ctrl)
0220         fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
0221 
0222     /* standby */
0223     ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
0224 
0225     if (fe->ops.i2c_gate_ctrl)
0226         fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
0227 
0228     if (ret)
0229         dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
0230 
0231     return ret;
0232 }
0233 
0234 static int tda18218_init(struct dvb_frontend *fe)
0235 {
0236     struct tda18218_priv *priv = fe->tuner_priv;
0237     int ret;
0238 
0239     /* TODO: calibrations */
0240 
0241     if (fe->ops.i2c_gate_ctrl)
0242         fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
0243 
0244     ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS);
0245 
0246     if (fe->ops.i2c_gate_ctrl)
0247         fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
0248 
0249     if (ret)
0250         dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
0251 
0252     return ret;
0253 }
0254 
0255 static void tda18218_release(struct dvb_frontend *fe)
0256 {
0257     kfree(fe->tuner_priv);
0258     fe->tuner_priv = NULL;
0259 }
0260 
0261 static const struct dvb_tuner_ops tda18218_tuner_ops = {
0262     .info = {
0263         .name              = "NXP TDA18218",
0264 
0265         .frequency_min_hz  = 174 * MHz,
0266         .frequency_max_hz  = 864 * MHz,
0267         .frequency_step_hz =   1 * kHz,
0268     },
0269 
0270     .release       = tda18218_release,
0271     .init          = tda18218_init,
0272     .sleep         = tda18218_sleep,
0273 
0274     .set_params    = tda18218_set_params,
0275 
0276     .get_if_frequency = tda18218_get_if_frequency,
0277 };
0278 
0279 struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
0280     struct i2c_adapter *i2c, struct tda18218_config *cfg)
0281 {
0282     struct tda18218_priv *priv = NULL;
0283     u8 val;
0284     int ret;
0285     /* chip default registers values */
0286     static u8 def_regs[] = {
0287         0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40,
0288         0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00,
0289         0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01,
0290         0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9,
0291         0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00,
0292         0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6
0293     };
0294 
0295     priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
0296     if (priv == NULL)
0297         return NULL;
0298 
0299     priv->cfg = cfg;
0300     priv->i2c = i2c;
0301     fe->tuner_priv = priv;
0302 
0303     if (fe->ops.i2c_gate_ctrl)
0304         fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
0305 
0306     /* check if the tuner is there */
0307     ret = tda18218_rd_reg(priv, R00_ID, &val);
0308     if (!ret)
0309         dev_dbg(&priv->i2c->dev, "%s: chip id=%02x\n", __func__, val);
0310     if (ret || val != def_regs[R00_ID]) {
0311         kfree(priv);
0312         return NULL;
0313     }
0314 
0315     dev_info(&priv->i2c->dev,
0316             "%s: NXP TDA18218HN successfully identified\n",
0317             KBUILD_MODNAME);
0318 
0319     memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
0320         sizeof(struct dvb_tuner_ops));
0321     memcpy(priv->regs, def_regs, sizeof(def_regs));
0322 
0323     /* loop-through enabled chip default register values */
0324     if (priv->cfg->loop_through) {
0325         priv->regs[R17_PD1] = 0xb0;
0326         priv->regs[R18_PD2] = 0x59;
0327     }
0328 
0329     /* standby */
0330     ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
0331     if (ret)
0332         dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
0333 
0334     if (fe->ops.i2c_gate_ctrl)
0335         fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
0336 
0337     return fe;
0338 }
0339 EXPORT_SYMBOL(tda18218_attach);
0340 
0341 MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
0342 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
0343 MODULE_LICENSE("GPL");