1 /* 2 * FCI FC2580 silicon tuner driver 3 * 4 * Copyright (C) 2012 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 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 #include "fc2580_priv.h" 22 23 /* 24 * TODO: 25 * I2C write and read works only for one single register. Multiple registers 26 * could not be accessed using normal register address auto-increment. 27 * There could be (very likely) register to change that behavior.... 28 * 29 * Due to that limitation functions: 30 * fc2580_wr_regs() 31 * fc2580_rd_regs() 32 * could not be used for accessing more than one register at once. 33 * 34 * TODO: 35 * Currently it blind writes bunch of static registers from the 36 * fc2580_freq_regs_lut[] when fc2580_set_params() is called. Add some 37 * logic to reduce unneeded register writes. 38 * There is also don't-care registers, initialized with value 0xff, and those 39 * are also written to the chip currently (yes, not wise). 40 */ 41 42 /* write multiple registers */ 43 static int fc2580_wr_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) 44 { 45 int ret; 46 u8 buf[1 + len]; 47 struct i2c_msg msg[1] = { 48 { 49 .addr = priv->cfg->i2c_addr, 50 .flags = 0, 51 .len = sizeof(buf), 52 .buf = buf, 53 } 54 }; 55 56 buf[0] = reg; 57 memcpy(&buf[1], val, len); 58 59 ret = i2c_transfer(priv->i2c, msg, 1); 60 if (ret == 1) { 61 ret = 0; 62 } else { 63 dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \ 64 "len=%d\n", KBUILD_MODNAME, ret, reg, len); 65 ret = -EREMOTEIO; 66 } 67 return ret; 68 } 69 70 /* read multiple registers */ 71 static int fc2580_rd_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) 72 { 73 int ret; 74 u8 buf[len]; 75 struct i2c_msg msg[2] = { 76 { 77 .addr = priv->cfg->i2c_addr, 78 .flags = 0, 79 .len = 1, 80 .buf = ®, 81 }, { 82 .addr = priv->cfg->i2c_addr, 83 .flags = I2C_M_RD, 84 .len = sizeof(buf), 85 .buf = buf, 86 } 87 }; 88 89 ret = i2c_transfer(priv->i2c, msg, 2); 90 if (ret == 2) { 91 memcpy(val, buf, len); 92 ret = 0; 93 } else { 94 dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \ 95 "len=%d\n", KBUILD_MODNAME, ret, reg, len); 96 ret = -EREMOTEIO; 97 } 98 99 return ret; 100 } 101 102 /* write single register */ 103 static int fc2580_wr_reg(struct fc2580_priv *priv, u8 reg, u8 val) 104 { 105 return fc2580_wr_regs(priv, reg, &val, 1); 106 } 107 108 /* read single register */ 109 static int fc2580_rd_reg(struct fc2580_priv *priv, u8 reg, u8 *val) 110 { 111 return fc2580_rd_regs(priv, reg, val, 1); 112 } 113 114 static int fc2580_set_params(struct dvb_frontend *fe) 115 { 116 struct fc2580_priv *priv = fe->tuner_priv; 117 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 118 int ret = 0, i; 119 unsigned int r_val, n_val, k_val, k_val_reg, f_ref; 120 u8 tmp_val, r18_val; 121 u64 f_vco; 122 123 /* 124 * Fractional-N synthesizer/PLL. 125 * Most likely all those PLL calculations are not correct. I am not 126 * sure, but it looks like it is divider based Fractional-N synthesizer. 127 * There is divider for reference clock too? 128 * Anyhow, synthesizer calculation results seems to be quite correct. 129 */ 130 131 dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \ 132 "bandwidth_hz=%d\n", __func__, 133 c->delivery_system, c->frequency, c->bandwidth_hz); 134 135 if (fe->ops.i2c_gate_ctrl) 136 fe->ops.i2c_gate_ctrl(fe, 1); 137 138 /* PLL */ 139 for (i = 0; i < ARRAY_SIZE(fc2580_pll_lut); i++) { 140 if (c->frequency <= fc2580_pll_lut[i].freq) 141 break; 142 } 143 144 if (i == ARRAY_SIZE(fc2580_pll_lut)) 145 goto err; 146 147 f_vco = c->frequency; 148 f_vco *= fc2580_pll_lut[i].div; 149 150 if (f_vco >= 2600000000UL) 151 tmp_val = 0x0e | fc2580_pll_lut[i].band; 152 else 153 tmp_val = 0x06 | fc2580_pll_lut[i].band; 154 155 ret = fc2580_wr_reg(priv, 0x02, tmp_val); 156 if (ret < 0) 157 goto err; 158 159 if (f_vco >= 2UL * 76 * priv->cfg->clock) { 160 r_val = 1; 161 r18_val = 0x00; 162 } else if (f_vco >= 1UL * 76 * priv->cfg->clock) { 163 r_val = 2; 164 r18_val = 0x10; 165 } else { 166 r_val = 4; 167 r18_val = 0x20; 168 } 169 170 f_ref = 2UL * priv->cfg->clock / r_val; 171 n_val = div_u64_rem(f_vco, f_ref, &k_val); 172 k_val_reg = 1UL * k_val * (1 << 20) / f_ref; 173 174 ret = fc2580_wr_reg(priv, 0x18, r18_val | ((k_val_reg >> 16) & 0xff)); 175 if (ret < 0) 176 goto err; 177 178 ret = fc2580_wr_reg(priv, 0x1a, (k_val_reg >> 8) & 0xff); 179 if (ret < 0) 180 goto err; 181 182 ret = fc2580_wr_reg(priv, 0x1b, (k_val_reg >> 0) & 0xff); 183 if (ret < 0) 184 goto err; 185 186 ret = fc2580_wr_reg(priv, 0x1c, n_val); 187 if (ret < 0) 188 goto err; 189 190 if (priv->cfg->clock >= 28000000) { 191 ret = fc2580_wr_reg(priv, 0x4b, 0x22); 192 if (ret < 0) 193 goto err; 194 } 195 196 if (fc2580_pll_lut[i].band == 0x00) { 197 if (c->frequency <= 794000000) 198 tmp_val = 0x9f; 199 else 200 tmp_val = 0x8f; 201 202 ret = fc2580_wr_reg(priv, 0x2d, tmp_val); 203 if (ret < 0) 204 goto err; 205 } 206 207 /* registers */ 208 for (i = 0; i < ARRAY_SIZE(fc2580_freq_regs_lut); i++) { 209 if (c->frequency <= fc2580_freq_regs_lut[i].freq) 210 break; 211 } 212 213 if (i == ARRAY_SIZE(fc2580_freq_regs_lut)) 214 goto err; 215 216 ret = fc2580_wr_reg(priv, 0x25, fc2580_freq_regs_lut[i].r25_val); 217 if (ret < 0) 218 goto err; 219 220 ret = fc2580_wr_reg(priv, 0x27, fc2580_freq_regs_lut[i].r27_val); 221 if (ret < 0) 222 goto err; 223 224 ret = fc2580_wr_reg(priv, 0x28, fc2580_freq_regs_lut[i].r28_val); 225 if (ret < 0) 226 goto err; 227 228 ret = fc2580_wr_reg(priv, 0x29, fc2580_freq_regs_lut[i].r29_val); 229 if (ret < 0) 230 goto err; 231 232 ret = fc2580_wr_reg(priv, 0x2b, fc2580_freq_regs_lut[i].r2b_val); 233 if (ret < 0) 234 goto err; 235 236 ret = fc2580_wr_reg(priv, 0x2c, fc2580_freq_regs_lut[i].r2c_val); 237 if (ret < 0) 238 goto err; 239 240 ret = fc2580_wr_reg(priv, 0x2d, fc2580_freq_regs_lut[i].r2d_val); 241 if (ret < 0) 242 goto err; 243 244 ret = fc2580_wr_reg(priv, 0x30, fc2580_freq_regs_lut[i].r30_val); 245 if (ret < 0) 246 goto err; 247 248 ret = fc2580_wr_reg(priv, 0x44, fc2580_freq_regs_lut[i].r44_val); 249 if (ret < 0) 250 goto err; 251 252 ret = fc2580_wr_reg(priv, 0x50, fc2580_freq_regs_lut[i].r50_val); 253 if (ret < 0) 254 goto err; 255 256 ret = fc2580_wr_reg(priv, 0x53, fc2580_freq_regs_lut[i].r53_val); 257 if (ret < 0) 258 goto err; 259 260 ret = fc2580_wr_reg(priv, 0x5f, fc2580_freq_regs_lut[i].r5f_val); 261 if (ret < 0) 262 goto err; 263 264 ret = fc2580_wr_reg(priv, 0x61, fc2580_freq_regs_lut[i].r61_val); 265 if (ret < 0) 266 goto err; 267 268 ret = fc2580_wr_reg(priv, 0x62, fc2580_freq_regs_lut[i].r62_val); 269 if (ret < 0) 270 goto err; 271 272 ret = fc2580_wr_reg(priv, 0x63, fc2580_freq_regs_lut[i].r63_val); 273 if (ret < 0) 274 goto err; 275 276 ret = fc2580_wr_reg(priv, 0x67, fc2580_freq_regs_lut[i].r67_val); 277 if (ret < 0) 278 goto err; 279 280 ret = fc2580_wr_reg(priv, 0x68, fc2580_freq_regs_lut[i].r68_val); 281 if (ret < 0) 282 goto err; 283 284 ret = fc2580_wr_reg(priv, 0x69, fc2580_freq_regs_lut[i].r69_val); 285 if (ret < 0) 286 goto err; 287 288 ret = fc2580_wr_reg(priv, 0x6a, fc2580_freq_regs_lut[i].r6a_val); 289 if (ret < 0) 290 goto err; 291 292 ret = fc2580_wr_reg(priv, 0x6b, fc2580_freq_regs_lut[i].r6b_val); 293 if (ret < 0) 294 goto err; 295 296 ret = fc2580_wr_reg(priv, 0x6c, fc2580_freq_regs_lut[i].r6c_val); 297 if (ret < 0) 298 goto err; 299 300 ret = fc2580_wr_reg(priv, 0x6d, fc2580_freq_regs_lut[i].r6d_val); 301 if (ret < 0) 302 goto err; 303 304 ret = fc2580_wr_reg(priv, 0x6e, fc2580_freq_regs_lut[i].r6e_val); 305 if (ret < 0) 306 goto err; 307 308 ret = fc2580_wr_reg(priv, 0x6f, fc2580_freq_regs_lut[i].r6f_val); 309 if (ret < 0) 310 goto err; 311 312 /* IF filters */ 313 for (i = 0; i < ARRAY_SIZE(fc2580_if_filter_lut); i++) { 314 if (c->bandwidth_hz <= fc2580_if_filter_lut[i].freq) 315 break; 316 } 317 318 if (i == ARRAY_SIZE(fc2580_if_filter_lut)) 319 goto err; 320 321 ret = fc2580_wr_reg(priv, 0x36, fc2580_if_filter_lut[i].r36_val); 322 if (ret < 0) 323 goto err; 324 325 ret = fc2580_wr_reg(priv, 0x37, 1UL * priv->cfg->clock * \ 326 fc2580_if_filter_lut[i].mul / 1000000000); 327 if (ret < 0) 328 goto err; 329 330 ret = fc2580_wr_reg(priv, 0x39, fc2580_if_filter_lut[i].r39_val); 331 if (ret < 0) 332 goto err; 333 334 /* calibration? */ 335 ret = fc2580_wr_reg(priv, 0x2e, 0x09); 336 if (ret < 0) 337 goto err; 338 339 for (i = 0; i < 5; i++) { 340 ret = fc2580_rd_reg(priv, 0x2f, &tmp_val); 341 if (ret < 0) 342 goto err; 343 344 /* done when [7:6] are set */ 345 if ((tmp_val & 0xc0) == 0xc0) 346 break; 347 348 ret = fc2580_wr_reg(priv, 0x2e, 0x01); 349 if (ret < 0) 350 goto err; 351 352 ret = fc2580_wr_reg(priv, 0x2e, 0x09); 353 if (ret < 0) 354 goto err; 355 356 usleep_range(5000, 25000); 357 } 358 359 dev_dbg(&priv->i2c->dev, "%s: loop=%i\n", __func__, i); 360 361 ret = fc2580_wr_reg(priv, 0x2e, 0x01); 362 if (ret < 0) 363 goto err; 364 365 if (fe->ops.i2c_gate_ctrl) 366 fe->ops.i2c_gate_ctrl(fe, 0); 367 368 return 0; 369 err: 370 if (fe->ops.i2c_gate_ctrl) 371 fe->ops.i2c_gate_ctrl(fe, 0); 372 373 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 374 return ret; 375 } 376 377 static int fc2580_init(struct dvb_frontend *fe) 378 { 379 struct fc2580_priv *priv = fe->tuner_priv; 380 int ret, i; 381 382 dev_dbg(&priv->i2c->dev, "%s:\n", __func__); 383 384 if (fe->ops.i2c_gate_ctrl) 385 fe->ops.i2c_gate_ctrl(fe, 1); 386 387 for (i = 0; i < ARRAY_SIZE(fc2580_init_reg_vals); i++) { 388 ret = fc2580_wr_reg(priv, fc2580_init_reg_vals[i].reg, 389 fc2580_init_reg_vals[i].val); 390 if (ret < 0) 391 goto err; 392 } 393 394 if (fe->ops.i2c_gate_ctrl) 395 fe->ops.i2c_gate_ctrl(fe, 0); 396 397 return 0; 398 err: 399 if (fe->ops.i2c_gate_ctrl) 400 fe->ops.i2c_gate_ctrl(fe, 0); 401 402 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 403 return ret; 404 } 405 406 static int fc2580_sleep(struct dvb_frontend *fe) 407 { 408 struct fc2580_priv *priv = fe->tuner_priv; 409 int ret; 410 411 dev_dbg(&priv->i2c->dev, "%s:\n", __func__); 412 413 if (fe->ops.i2c_gate_ctrl) 414 fe->ops.i2c_gate_ctrl(fe, 1); 415 416 ret = fc2580_wr_reg(priv, 0x02, 0x0a); 417 if (ret < 0) 418 goto err; 419 420 if (fe->ops.i2c_gate_ctrl) 421 fe->ops.i2c_gate_ctrl(fe, 0); 422 423 return 0; 424 err: 425 if (fe->ops.i2c_gate_ctrl) 426 fe->ops.i2c_gate_ctrl(fe, 0); 427 428 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 429 return ret; 430 } 431 432 static int fc2580_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) 433 { 434 struct fc2580_priv *priv = fe->tuner_priv; 435 436 dev_dbg(&priv->i2c->dev, "%s:\n", __func__); 437 438 *frequency = 0; /* Zero-IF */ 439 440 return 0; 441 } 442 443 static int fc2580_release(struct dvb_frontend *fe) 444 { 445 struct fc2580_priv *priv = fe->tuner_priv; 446 447 dev_dbg(&priv->i2c->dev, "%s:\n", __func__); 448 449 kfree(fe->tuner_priv); 450 451 return 0; 452 } 453 454 static const struct dvb_tuner_ops fc2580_tuner_ops = { 455 .info = { 456 .name = "FCI FC2580", 457 .frequency_min = 174000000, 458 .frequency_max = 862000000, 459 }, 460 461 .release = fc2580_release, 462 463 .init = fc2580_init, 464 .sleep = fc2580_sleep, 465 .set_params = fc2580_set_params, 466 467 .get_if_frequency = fc2580_get_if_frequency, 468 }; 469 470 struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe, 471 struct i2c_adapter *i2c, const struct fc2580_config *cfg) 472 { 473 struct fc2580_priv *priv; 474 int ret; 475 u8 chip_id; 476 477 if (fe->ops.i2c_gate_ctrl) 478 fe->ops.i2c_gate_ctrl(fe, 1); 479 480 priv = kzalloc(sizeof(struct fc2580_priv), GFP_KERNEL); 481 if (!priv) { 482 ret = -ENOMEM; 483 dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); 484 goto err; 485 } 486 487 priv->cfg = cfg; 488 priv->i2c = i2c; 489 490 /* check if the tuner is there */ 491 ret = fc2580_rd_reg(priv, 0x01, &chip_id); 492 if (ret < 0) 493 goto err; 494 495 dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id); 496 497 switch (chip_id) { 498 case 0x56: 499 case 0x5a: 500 break; 501 default: 502 goto err; 503 } 504 505 dev_info(&priv->i2c->dev, 506 "%s: FCI FC2580 successfully identified\n", 507 KBUILD_MODNAME); 508 509 fe->tuner_priv = priv; 510 memcpy(&fe->ops.tuner_ops, &fc2580_tuner_ops, 511 sizeof(struct dvb_tuner_ops)); 512 513 if (fe->ops.i2c_gate_ctrl) 514 fe->ops.i2c_gate_ctrl(fe, 0); 515 516 return fe; 517 err: 518 if (fe->ops.i2c_gate_ctrl) 519 fe->ops.i2c_gate_ctrl(fe, 0); 520 521 dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); 522 kfree(priv); 523 return NULL; 524 } 525 EXPORT_SYMBOL(fc2580_attach); 526 527 MODULE_DESCRIPTION("FCI FC2580 silicon tuner driver"); 528 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 529 MODULE_LICENSE("GPL"); 530