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