1/* 2 * Sony CXD2820R demodulator 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 * 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 22#include "cxd2820r_priv.h" 23 24int cxd2820r_debug; 25module_param_named(debug, cxd2820r_debug, int, 0644); 26MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 27 28/* write multiple registers */ 29static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg, 30 u8 *val, int len) 31{ 32 int ret; 33 u8 buf[len+1]; 34 struct i2c_msg msg[1] = { 35 { 36 .addr = i2c, 37 .flags = 0, 38 .len = sizeof(buf), 39 .buf = buf, 40 } 41 }; 42 43 buf[0] = reg; 44 memcpy(&buf[1], val, len); 45 46 ret = i2c_transfer(priv->i2c, msg, 1); 47 if (ret == 1) { 48 ret = 0; 49 } else { 50 warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len); 51 ret = -EREMOTEIO; 52 } 53 return ret; 54} 55 56/* read multiple registers */ 57static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg, 58 u8 *val, int len) 59{ 60 int ret; 61 u8 buf[len]; 62 struct i2c_msg msg[2] = { 63 { 64 .addr = i2c, 65 .flags = 0, 66 .len = 1, 67 .buf = ®, 68 }, { 69 .addr = i2c, 70 .flags = I2C_M_RD, 71 .len = sizeof(buf), 72 .buf = buf, 73 } 74 }; 75 76 ret = i2c_transfer(priv->i2c, msg, 2); 77 if (ret == 2) { 78 memcpy(val, buf, len); 79 ret = 0; 80 } else { 81 warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len); 82 ret = -EREMOTEIO; 83 } 84 85 return ret; 86} 87 88/* write multiple registers */ 89int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val, 90 int len) 91{ 92 int ret; 93 u8 i2c_addr; 94 u8 reg = (reginfo >> 0) & 0xff; 95 u8 bank = (reginfo >> 8) & 0xff; 96 u8 i2c = (reginfo >> 16) & 0x01; 97 98 /* select I2C */ 99 if (i2c) 100 i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */ 101 else 102 i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */ 103 104 /* switch bank if needed */ 105 if (bank != priv->bank[i2c]) { 106 ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1); 107 if (ret) 108 return ret; 109 priv->bank[i2c] = bank; 110 } 111 return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len); 112} 113 114/* read multiple registers */ 115int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val, 116 int len) 117{ 118 int ret; 119 u8 i2c_addr; 120 u8 reg = (reginfo >> 0) & 0xff; 121 u8 bank = (reginfo >> 8) & 0xff; 122 u8 i2c = (reginfo >> 16) & 0x01; 123 124 /* select I2C */ 125 if (i2c) 126 i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */ 127 else 128 i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */ 129 130 /* switch bank if needed */ 131 if (bank != priv->bank[i2c]) { 132 ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1); 133 if (ret) 134 return ret; 135 priv->bank[i2c] = bank; 136 } 137 return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len); 138} 139 140/* write single register */ 141int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val) 142{ 143 return cxd2820r_wr_regs(priv, reg, &val, 1); 144} 145 146/* read single register */ 147int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val) 148{ 149 return cxd2820r_rd_regs(priv, reg, val, 1); 150} 151 152/* write single register with mask */ 153int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val, 154 u8 mask) 155{ 156 int ret; 157 u8 tmp; 158 159 /* no need for read if whole reg is written */ 160 if (mask != 0xff) { 161 ret = cxd2820r_rd_reg(priv, reg, &tmp); 162 if (ret) 163 return ret; 164 165 val &= mask; 166 tmp &= ~mask; 167 val |= tmp; 168 } 169 170 return cxd2820r_wr_reg(priv, reg, val); 171} 172 173int cxd2820r_gpio(struct dvb_frontend *fe) 174{ 175 struct cxd2820r_priv *priv = fe->demodulator_priv; 176 int ret, i; 177 u8 *gpio, tmp0, tmp1; 178 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 179 180 switch (fe->dtv_property_cache.delivery_system) { 181 case SYS_DVBT: 182 gpio = priv->cfg.gpio_dvbt; 183 break; 184 case SYS_DVBT2: 185 gpio = priv->cfg.gpio_dvbt2; 186 break; 187 case SYS_DVBC_ANNEX_AC: 188 gpio = priv->cfg.gpio_dvbc; 189 break; 190 default: 191 ret = -EINVAL; 192 goto error; 193 } 194 195 /* update GPIOs only when needed */ 196 if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio))) 197 return 0; 198 199 tmp0 = 0x00; 200 tmp1 = 0x00; 201 for (i = 0; i < sizeof(priv->gpio); i++) { 202 /* enable / disable */ 203 if (gpio[i] & CXD2820R_GPIO_E) 204 tmp0 |= (2 << 6) >> (2 * i); 205 else 206 tmp0 |= (1 << 6) >> (2 * i); 207 208 /* input / output */ 209 if (gpio[i] & CXD2820R_GPIO_I) 210 tmp1 |= (1 << (3 + i)); 211 else 212 tmp1 |= (0 << (3 + i)); 213 214 /* high / low */ 215 if (gpio[i] & CXD2820R_GPIO_H) 216 tmp1 |= (1 << (0 + i)); 217 else 218 tmp1 |= (0 << (0 + i)); 219 220 dbg("%s: GPIO i=%d %02x %02x", __func__, i, tmp0, tmp1); 221 } 222 223 dbg("%s: wr gpio=%02x %02x", __func__, tmp0, tmp1); 224 225 /* write bits [7:2] */ 226 ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc); 227 if (ret) 228 goto error; 229 230 /* write bits [5:0] */ 231 ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f); 232 if (ret) 233 goto error; 234 235 memcpy(priv->gpio, gpio, sizeof(priv->gpio)); 236 237 return ret; 238error: 239 dbg("%s: failed:%d", __func__, ret); 240 return ret; 241} 242 243/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */ 244u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor) 245{ 246 return div_u64(dividend + (divisor / 2), divisor); 247} 248 249static int cxd2820r_set_frontend(struct dvb_frontend *fe) 250{ 251 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 252 int ret; 253 254 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 255 switch (c->delivery_system) { 256 case SYS_DVBT: 257 ret = cxd2820r_init_t(fe); 258 if (ret < 0) 259 goto err; 260 ret = cxd2820r_set_frontend_t(fe); 261 if (ret < 0) 262 goto err; 263 break; 264 case SYS_DVBT2: 265 ret = cxd2820r_init_t(fe); 266 if (ret < 0) 267 goto err; 268 ret = cxd2820r_set_frontend_t2(fe); 269 if (ret < 0) 270 goto err; 271 break; 272 case SYS_DVBC_ANNEX_A: 273 ret = cxd2820r_init_c(fe); 274 if (ret < 0) 275 goto err; 276 ret = cxd2820r_set_frontend_c(fe); 277 if (ret < 0) 278 goto err; 279 break; 280 default: 281 dbg("%s: error state=%d", __func__, fe->dtv_property_cache.delivery_system); 282 ret = -EINVAL; 283 break; 284 } 285err: 286 return ret; 287} 288static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status) 289{ 290 int ret; 291 292 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 293 switch (fe->dtv_property_cache.delivery_system) { 294 case SYS_DVBT: 295 ret = cxd2820r_read_status_t(fe, status); 296 break; 297 case SYS_DVBT2: 298 ret = cxd2820r_read_status_t2(fe, status); 299 break; 300 case SYS_DVBC_ANNEX_A: 301 ret = cxd2820r_read_status_c(fe, status); 302 break; 303 default: 304 ret = -EINVAL; 305 break; 306 } 307 return ret; 308} 309 310static int cxd2820r_get_frontend(struct dvb_frontend *fe) 311{ 312 struct cxd2820r_priv *priv = fe->demodulator_priv; 313 int ret; 314 315 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 316 317 if (priv->delivery_system == SYS_UNDEFINED) 318 return 0; 319 320 switch (fe->dtv_property_cache.delivery_system) { 321 case SYS_DVBT: 322 ret = cxd2820r_get_frontend_t(fe); 323 break; 324 case SYS_DVBT2: 325 ret = cxd2820r_get_frontend_t2(fe); 326 break; 327 case SYS_DVBC_ANNEX_A: 328 ret = cxd2820r_get_frontend_c(fe); 329 break; 330 default: 331 ret = -EINVAL; 332 break; 333 } 334 return ret; 335} 336 337static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber) 338{ 339 int ret; 340 341 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 342 switch (fe->dtv_property_cache.delivery_system) { 343 case SYS_DVBT: 344 ret = cxd2820r_read_ber_t(fe, ber); 345 break; 346 case SYS_DVBT2: 347 ret = cxd2820r_read_ber_t2(fe, ber); 348 break; 349 case SYS_DVBC_ANNEX_A: 350 ret = cxd2820r_read_ber_c(fe, ber); 351 break; 352 default: 353 ret = -EINVAL; 354 break; 355 } 356 return ret; 357} 358 359static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 360{ 361 int ret; 362 363 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 364 switch (fe->dtv_property_cache.delivery_system) { 365 case SYS_DVBT: 366 ret = cxd2820r_read_signal_strength_t(fe, strength); 367 break; 368 case SYS_DVBT2: 369 ret = cxd2820r_read_signal_strength_t2(fe, strength); 370 break; 371 case SYS_DVBC_ANNEX_A: 372 ret = cxd2820r_read_signal_strength_c(fe, strength); 373 break; 374 default: 375 ret = -EINVAL; 376 break; 377 } 378 return ret; 379} 380 381static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr) 382{ 383 int ret; 384 385 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 386 switch (fe->dtv_property_cache.delivery_system) { 387 case SYS_DVBT: 388 ret = cxd2820r_read_snr_t(fe, snr); 389 break; 390 case SYS_DVBT2: 391 ret = cxd2820r_read_snr_t2(fe, snr); 392 break; 393 case SYS_DVBC_ANNEX_A: 394 ret = cxd2820r_read_snr_c(fe, snr); 395 break; 396 default: 397 ret = -EINVAL; 398 break; 399 } 400 return ret; 401} 402 403static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 404{ 405 int ret; 406 407 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 408 switch (fe->dtv_property_cache.delivery_system) { 409 case SYS_DVBT: 410 ret = cxd2820r_read_ucblocks_t(fe, ucblocks); 411 break; 412 case SYS_DVBT2: 413 ret = cxd2820r_read_ucblocks_t2(fe, ucblocks); 414 break; 415 case SYS_DVBC_ANNEX_A: 416 ret = cxd2820r_read_ucblocks_c(fe, ucblocks); 417 break; 418 default: 419 ret = -EINVAL; 420 break; 421 } 422 return ret; 423} 424 425static int cxd2820r_init(struct dvb_frontend *fe) 426{ 427 return 0; 428} 429 430static int cxd2820r_sleep(struct dvb_frontend *fe) 431{ 432 int ret; 433 434 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 435 switch (fe->dtv_property_cache.delivery_system) { 436 case SYS_DVBT: 437 ret = cxd2820r_sleep_t(fe); 438 break; 439 case SYS_DVBT2: 440 ret = cxd2820r_sleep_t2(fe); 441 break; 442 case SYS_DVBC_ANNEX_A: 443 ret = cxd2820r_sleep_c(fe); 444 break; 445 default: 446 ret = -EINVAL; 447 break; 448 } 449 return ret; 450} 451 452static int cxd2820r_get_tune_settings(struct dvb_frontend *fe, 453 struct dvb_frontend_tune_settings *s) 454{ 455 int ret; 456 457 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 458 switch (fe->dtv_property_cache.delivery_system) { 459 case SYS_DVBT: 460 ret = cxd2820r_get_tune_settings_t(fe, s); 461 break; 462 case SYS_DVBT2: 463 ret = cxd2820r_get_tune_settings_t2(fe, s); 464 break; 465 case SYS_DVBC_ANNEX_A: 466 ret = cxd2820r_get_tune_settings_c(fe, s); 467 break; 468 default: 469 ret = -EINVAL; 470 break; 471 } 472 return ret; 473} 474 475static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) 476{ 477 struct cxd2820r_priv *priv = fe->demodulator_priv; 478 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 479 int ret, i; 480 fe_status_t status = 0; 481 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 482 483 /* switch between DVB-T and DVB-T2 when tune fails */ 484 if (priv->last_tune_failed) { 485 if (priv->delivery_system == SYS_DVBT) { 486 ret = cxd2820r_sleep_t(fe); 487 if (ret) 488 goto error; 489 490 c->delivery_system = SYS_DVBT2; 491 } else if (priv->delivery_system == SYS_DVBT2) { 492 ret = cxd2820r_sleep_t2(fe); 493 if (ret) 494 goto error; 495 496 c->delivery_system = SYS_DVBT; 497 } 498 } 499 500 /* set frontend */ 501 ret = cxd2820r_set_frontend(fe); 502 if (ret) 503 goto error; 504 505 506 /* frontend lock wait loop count */ 507 switch (priv->delivery_system) { 508 case SYS_DVBT: 509 case SYS_DVBC_ANNEX_A: 510 i = 20; 511 break; 512 case SYS_DVBT2: 513 i = 40; 514 break; 515 case SYS_UNDEFINED: 516 default: 517 i = 0; 518 break; 519 } 520 521 /* wait frontend lock */ 522 for (; i > 0; i--) { 523 dbg("%s: LOOP=%d", __func__, i); 524 msleep(50); 525 ret = cxd2820r_read_status(fe, &status); 526 if (ret) 527 goto error; 528 529 if (status & FE_HAS_SIGNAL) 530 break; 531 } 532 533 /* check if we have a valid signal */ 534 if (status) { 535 priv->last_tune_failed = 0; 536 return DVBFE_ALGO_SEARCH_SUCCESS; 537 } else { 538 priv->last_tune_failed = 1; 539 return DVBFE_ALGO_SEARCH_AGAIN; 540 } 541 542error: 543 dbg("%s: failed:%d", __func__, ret); 544 return DVBFE_ALGO_SEARCH_ERROR; 545} 546 547static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe) 548{ 549 return DVBFE_ALGO_CUSTOM; 550} 551 552static void cxd2820r_release(struct dvb_frontend *fe) 553{ 554 struct cxd2820r_priv *priv = fe->demodulator_priv; 555 dbg("%s", __func__); 556 557 kfree(priv); 558 return; 559} 560 561static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 562{ 563 struct cxd2820r_priv *priv = fe->demodulator_priv; 564 dbg("%s: %d", __func__, enable); 565 566 /* Bit 0 of reg 0xdb in bank 0x00 controls I2C repeater */ 567 return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1); 568} 569 570static const struct dvb_frontend_ops cxd2820r_ops = { 571 .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A }, 572 /* default: DVB-T/T2 */ 573 .info = { 574 .name = "Sony CXD2820R", 575 576 .caps = FE_CAN_FEC_1_2 | 577 FE_CAN_FEC_2_3 | 578 FE_CAN_FEC_3_4 | 579 FE_CAN_FEC_5_6 | 580 FE_CAN_FEC_7_8 | 581 FE_CAN_FEC_AUTO | 582 FE_CAN_QPSK | 583 FE_CAN_QAM_16 | 584 FE_CAN_QAM_32 | 585 FE_CAN_QAM_64 | 586 FE_CAN_QAM_128 | 587 FE_CAN_QAM_256 | 588 FE_CAN_QAM_AUTO | 589 FE_CAN_TRANSMISSION_MODE_AUTO | 590 FE_CAN_GUARD_INTERVAL_AUTO | 591 FE_CAN_HIERARCHY_AUTO | 592 FE_CAN_MUTE_TS | 593 FE_CAN_2G_MODULATION 594 }, 595 596 .release = cxd2820r_release, 597 .init = cxd2820r_init, 598 .sleep = cxd2820r_sleep, 599 600 .get_tune_settings = cxd2820r_get_tune_settings, 601 .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl, 602 603 .get_frontend = cxd2820r_get_frontend, 604 605 .get_frontend_algo = cxd2820r_get_frontend_algo, 606 .search = cxd2820r_search, 607 608 .read_status = cxd2820r_read_status, 609 .read_snr = cxd2820r_read_snr, 610 .read_ber = cxd2820r_read_ber, 611 .read_ucblocks = cxd2820r_read_ucblocks, 612 .read_signal_strength = cxd2820r_read_signal_strength, 613}; 614 615struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, 616 struct i2c_adapter *i2c) 617{ 618 struct cxd2820r_priv *priv = NULL; 619 int ret; 620 u8 tmp; 621 622 priv = kzalloc(sizeof (struct cxd2820r_priv), GFP_KERNEL); 623 if (!priv) 624 goto error; 625 626 priv->i2c = i2c; 627 memcpy(&priv->cfg, cfg, sizeof (struct cxd2820r_config)); 628 629 priv->bank[0] = priv->bank[1] = 0xff; 630 ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp); 631 dbg("%s: chip id=%02x", __func__, tmp); 632 if (ret || tmp != 0xe1) 633 goto error; 634 635 memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof (struct dvb_frontend_ops)); 636 priv->fe.demodulator_priv = priv; 637 return &priv->fe; 638error: 639 kfree(priv); 640 return NULL; 641} 642EXPORT_SYMBOL(cxd2820r_attach); 643 644MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 645MODULE_DESCRIPTION("Sony CXD2820R demodulator driver"); 646MODULE_LICENSE("GPL"); 647