tda18218.c (8205B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * NXP TDA18218HN silicon tuner driver 4 * 5 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> 6 */ 7 8#include "tda18218_priv.h" 9 10/* Max transfer size done by I2C transfer functions */ 11#define MAX_XFER_SIZE 64 12 13/* write multiple registers */ 14static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len) 15{ 16 int ret = 0, len2, remaining; 17 u8 buf[MAX_XFER_SIZE]; 18 struct i2c_msg msg[1] = { 19 { 20 .addr = priv->cfg->i2c_address, 21 .flags = 0, 22 .buf = buf, 23 } 24 }; 25 26 if (1 + len > sizeof(buf)) { 27 dev_warn(&priv->i2c->dev, 28 "%s: i2c wr reg=%04x: len=%d is too big!\n", 29 KBUILD_MODNAME, reg, len); 30 return -EINVAL; 31 } 32 33 for (remaining = len; remaining > 0; 34 remaining -= (priv->cfg->i2c_wr_max - 1)) { 35 len2 = remaining; 36 if (len2 > (priv->cfg->i2c_wr_max - 1)) 37 len2 = (priv->cfg->i2c_wr_max - 1); 38 39 msg[0].len = 1 + len2; 40 buf[0] = reg + len - remaining; 41 memcpy(&buf[1], &val[len - remaining], len2); 42 43 ret = i2c_transfer(priv->i2c, msg, 1); 44 if (ret != 1) 45 break; 46 } 47 48 if (ret == 1) { 49 ret = 0; 50 } else { 51 dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \ 52 "len=%d\n", KBUILD_MODNAME, ret, reg, len); 53 ret = -EREMOTEIO; 54 } 55 56 return ret; 57} 58 59/* read multiple registers */ 60static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len) 61{ 62 int ret; 63 u8 buf[MAX_XFER_SIZE]; /* we must start read always from reg 0x00 */ 64 struct i2c_msg msg[2] = { 65 { 66 .addr = priv->cfg->i2c_address, 67 .flags = 0, 68 .len = 1, 69 .buf = "\x00", 70 }, { 71 .addr = priv->cfg->i2c_address, 72 .flags = I2C_M_RD, 73 .len = reg + len, 74 .buf = buf, 75 } 76 }; 77 78 if (reg + len > sizeof(buf)) { 79 dev_warn(&priv->i2c->dev, 80 "%s: i2c wr reg=%04x: len=%d is too big!\n", 81 KBUILD_MODNAME, reg, len); 82 return -EINVAL; 83 } 84 85 ret = i2c_transfer(priv->i2c, msg, 2); 86 if (ret == 2) { 87 memcpy(val, &buf[reg], len); 88 ret = 0; 89 } else { 90 dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \ 91 "len=%d\n", KBUILD_MODNAME, ret, reg, len); 92 ret = -EREMOTEIO; 93 } 94 95 return ret; 96} 97 98/* write single register */ 99static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val) 100{ 101 return tda18218_wr_regs(priv, reg, &val, 1); 102} 103 104/* read single register */ 105 106static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val) 107{ 108 return tda18218_rd_regs(priv, reg, val, 1); 109} 110 111static int tda18218_set_params(struct dvb_frontend *fe) 112{ 113 struct tda18218_priv *priv = fe->tuner_priv; 114 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 115 u32 bw = c->bandwidth_hz; 116 int ret; 117 u8 buf[3], i, BP_Filter, LP_Fc; 118 u32 LO_Frac; 119 /* TODO: find out correct AGC algorithm */ 120 u8 agc[][2] = { 121 { R20_AGC11, 0x60 }, 122 { R23_AGC21, 0x02 }, 123 { R20_AGC11, 0xa0 }, 124 { R23_AGC21, 0x09 }, 125 { R20_AGC11, 0xe0 }, 126 { R23_AGC21, 0x0c }, 127 { R20_AGC11, 0x40 }, 128 { R23_AGC21, 0x01 }, 129 { R20_AGC11, 0x80 }, 130 { R23_AGC21, 0x08 }, 131 { R20_AGC11, 0xc0 }, 132 { R23_AGC21, 0x0b }, 133 { R24_AGC22, 0x1c }, 134 { R24_AGC22, 0x0c }, 135 }; 136 137 if (fe->ops.i2c_gate_ctrl) 138 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ 139 140 /* low-pass filter cut-off frequency */ 141 if (bw <= 6000000) { 142 LP_Fc = 0; 143 priv->if_frequency = 3000000; 144 } else if (bw <= 7000000) { 145 LP_Fc = 1; 146 priv->if_frequency = 3500000; 147 } else { 148 LP_Fc = 2; 149 priv->if_frequency = 4000000; 150 } 151 152 LO_Frac = c->frequency + priv->if_frequency; 153 154 /* band-pass filter */ 155 if (LO_Frac < 188000000) 156 BP_Filter = 3; 157 else if (LO_Frac < 253000000) 158 BP_Filter = 4; 159 else if (LO_Frac < 343000000) 160 BP_Filter = 5; 161 else 162 BP_Filter = 6; 163 164 buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */ 165 buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */ 166 buf[2] = priv->regs[R1C_AGC2B]; 167 ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3); 168 if (ret) 169 goto error; 170 171 buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */ 172 buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */ 173 buf[2] = (LO_Frac / 1000) << 4 | 174 (priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */ 175 ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3); 176 if (ret) 177 goto error; 178 179 buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */ 180 ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1); 181 if (ret) 182 goto error; 183 184 buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */ 185 ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1); 186 if (ret) 187 goto error; 188 189 /* trigger AGC */ 190 for (i = 0; i < ARRAY_SIZE(agc); i++) { 191 ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]); 192 if (ret) 193 goto error; 194 } 195 196error: 197 if (fe->ops.i2c_gate_ctrl) 198 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ 199 200 if (ret) 201 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 202 203 return ret; 204} 205 206static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) 207{ 208 struct tda18218_priv *priv = fe->tuner_priv; 209 *frequency = priv->if_frequency; 210 dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d\n", __func__, *frequency); 211 return 0; 212} 213 214static int tda18218_sleep(struct dvb_frontend *fe) 215{ 216 struct tda18218_priv *priv = fe->tuner_priv; 217 int ret; 218 219 if (fe->ops.i2c_gate_ctrl) 220 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ 221 222 /* standby */ 223 ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0)); 224 225 if (fe->ops.i2c_gate_ctrl) 226 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ 227 228 if (ret) 229 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 230 231 return ret; 232} 233 234static int tda18218_init(struct dvb_frontend *fe) 235{ 236 struct tda18218_priv *priv = fe->tuner_priv; 237 int ret; 238 239 /* TODO: calibrations */ 240 241 if (fe->ops.i2c_gate_ctrl) 242 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ 243 244 ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS); 245 246 if (fe->ops.i2c_gate_ctrl) 247 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ 248 249 if (ret) 250 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 251 252 return ret; 253} 254 255static void tda18218_release(struct dvb_frontend *fe) 256{ 257 kfree(fe->tuner_priv); 258 fe->tuner_priv = NULL; 259} 260 261static const struct dvb_tuner_ops tda18218_tuner_ops = { 262 .info = { 263 .name = "NXP TDA18218", 264 265 .frequency_min_hz = 174 * MHz, 266 .frequency_max_hz = 864 * MHz, 267 .frequency_step_hz = 1 * kHz, 268 }, 269 270 .release = tda18218_release, 271 .init = tda18218_init, 272 .sleep = tda18218_sleep, 273 274 .set_params = tda18218_set_params, 275 276 .get_if_frequency = tda18218_get_if_frequency, 277}; 278 279struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, 280 struct i2c_adapter *i2c, struct tda18218_config *cfg) 281{ 282 struct tda18218_priv *priv = NULL; 283 u8 val; 284 int ret; 285 /* chip default registers values */ 286 static u8 def_regs[] = { 287 0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40, 288 0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00, 289 0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01, 290 0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9, 291 0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00, 292 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6 293 }; 294 295 priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL); 296 if (priv == NULL) 297 return NULL; 298 299 priv->cfg = cfg; 300 priv->i2c = i2c; 301 fe->tuner_priv = priv; 302 303 if (fe->ops.i2c_gate_ctrl) 304 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ 305 306 /* check if the tuner is there */ 307 ret = tda18218_rd_reg(priv, R00_ID, &val); 308 if (!ret) 309 dev_dbg(&priv->i2c->dev, "%s: chip id=%02x\n", __func__, val); 310 if (ret || val != def_regs[R00_ID]) { 311 kfree(priv); 312 return NULL; 313 } 314 315 dev_info(&priv->i2c->dev, 316 "%s: NXP TDA18218HN successfully identified\n", 317 KBUILD_MODNAME); 318 319 memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops, 320 sizeof(struct dvb_tuner_ops)); 321 memcpy(priv->regs, def_regs, sizeof(def_regs)); 322 323 /* loop-through enabled chip default register values */ 324 if (priv->cfg->loop_through) { 325 priv->regs[R17_PD1] = 0xb0; 326 priv->regs[R18_PD2] = 0x59; 327 } 328 329 /* standby */ 330 ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0)); 331 if (ret) 332 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 333 334 if (fe->ops.i2c_gate_ctrl) 335 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ 336 337 return fe; 338} 339EXPORT_SYMBOL(tda18218_attach); 340 341MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver"); 342MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 343MODULE_LICENSE("GPL");