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