1/* 2 * Support for LG2160 - ATSC/MH 3 * 4 * Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org> 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 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * 20 */ 21 22#include <linux/jiffies.h> 23#include <linux/dvb/frontend.h> 24#include "lg2160.h" 25 26static int debug; 27module_param(debug, int, 0644); 28MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))"); 29 30#define DBG_INFO 1 31#define DBG_REG 2 32 33#define lg_printk(kern, fmt, arg...) \ 34 printk(kern "%s: " fmt, __func__, ##arg) 35 36#define lg_info(fmt, arg...) printk(KERN_INFO "lg2160: " fmt, ##arg) 37#define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg) 38#define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg) 39#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \ 40 lg_printk(KERN_DEBUG, fmt, ##arg) 41#define lg_reg(fmt, arg...) if (debug & DBG_REG) \ 42 lg_printk(KERN_DEBUG, fmt, ##arg) 43 44#define lg_fail(ret) \ 45({ \ 46 int __ret; \ 47 __ret = (ret < 0); \ 48 if (__ret) \ 49 lg_err("error %d on line %d\n", ret, __LINE__); \ 50 __ret; \ 51}) 52 53struct lg216x_state { 54 struct i2c_adapter *i2c_adap; 55 const struct lg2160_config *cfg; 56 57 struct dvb_frontend frontend; 58 59 u32 current_frequency; 60 u8 parade_id; 61 u8 fic_ver; 62 unsigned int last_reset; 63}; 64 65/* ------------------------------------------------------------------------ */ 66 67static int lg216x_write_reg(struct lg216x_state *state, u16 reg, u8 val) 68{ 69 int ret; 70 u8 buf[] = { reg >> 8, reg & 0xff, val }; 71 struct i2c_msg msg = { 72 .addr = state->cfg->i2c_addr, .flags = 0, 73 .buf = buf, .len = 3, 74 }; 75 76 lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val); 77 78 ret = i2c_transfer(state->i2c_adap, &msg, 1); 79 80 if (ret != 1) { 81 lg_err("error (addr %02x %02x <- %02x, err = %i)\n", 82 msg.buf[0], msg.buf[1], msg.buf[2], ret); 83 if (ret < 0) 84 return ret; 85 else 86 return -EREMOTEIO; 87 } 88 return 0; 89} 90 91static int lg216x_read_reg(struct lg216x_state *state, u16 reg, u8 *val) 92{ 93 int ret; 94 u8 reg_buf[] = { reg >> 8, reg & 0xff }; 95 struct i2c_msg msg[] = { 96 { .addr = state->cfg->i2c_addr, 97 .flags = 0, .buf = reg_buf, .len = 2 }, 98 { .addr = state->cfg->i2c_addr, 99 .flags = I2C_M_RD, .buf = val, .len = 1 }, 100 }; 101 102 lg_reg("reg: 0x%04x\n", reg); 103 104 ret = i2c_transfer(state->i2c_adap, msg, 2); 105 106 if (ret != 2) { 107 lg_err("error (addr %02x reg %04x error (ret == %i)\n", 108 state->cfg->i2c_addr, reg, ret); 109 if (ret < 0) 110 return ret; 111 else 112 return -EREMOTEIO; 113 } 114 return 0; 115} 116 117struct lg216x_reg { 118 u16 reg; 119 u8 val; 120}; 121 122static int lg216x_write_regs(struct lg216x_state *state, 123 struct lg216x_reg *regs, int len) 124{ 125 int i, ret; 126 127 lg_reg("writing %d registers...\n", len); 128 129 for (i = 0; i < len; i++) { 130 ret = lg216x_write_reg(state, regs[i].reg, regs[i].val); 131 if (lg_fail(ret)) 132 return ret; 133 } 134 return 0; 135} 136 137static int lg216x_set_reg_bit(struct lg216x_state *state, 138 u16 reg, int bit, int onoff) 139{ 140 u8 val; 141 int ret; 142 143 lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff); 144 145 ret = lg216x_read_reg(state, reg, &val); 146 if (lg_fail(ret)) 147 goto fail; 148 149 val &= ~(1 << bit); 150 val |= (onoff & 1) << bit; 151 152 ret = lg216x_write_reg(state, reg, val); 153 lg_fail(ret); 154fail: 155 return ret; 156} 157 158/* ------------------------------------------------------------------------ */ 159 160static int lg216x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 161{ 162 struct lg216x_state *state = fe->demodulator_priv; 163 int ret; 164 165 if (state->cfg->deny_i2c_rptr) 166 return 0; 167 168 lg_dbg("(%d)\n", enable); 169 170 ret = lg216x_set_reg_bit(state, 0x0000, 0, enable ? 0 : 1); 171 172 msleep(1); 173 174 return ret; 175} 176 177static int lg216x_soft_reset(struct lg216x_state *state) 178{ 179 int ret; 180 181 lg_dbg("\n"); 182 183 ret = lg216x_write_reg(state, 0x0002, 0x00); 184 if (lg_fail(ret)) 185 goto fail; 186 187 msleep(20); 188 ret = lg216x_write_reg(state, 0x0002, 0x01); 189 if (lg_fail(ret)) 190 goto fail; 191 192 state->last_reset = jiffies_to_msecs(jiffies); 193fail: 194 return ret; 195} 196 197static int lg216x_initialize(struct lg216x_state *state) 198{ 199 int ret; 200 201 static struct lg216x_reg lg2160_init[] = { 202#if 0 203 { .reg = 0x0015, .val = 0xe6 }, 204#else 205 { .reg = 0x0015, .val = 0xf7 }, 206 { .reg = 0x001b, .val = 0x52 }, 207 { .reg = 0x0208, .val = 0x00 }, 208 { .reg = 0x0209, .val = 0x82 }, 209 { .reg = 0x0210, .val = 0xf9 }, 210 { .reg = 0x020a, .val = 0x00 }, 211 { .reg = 0x020b, .val = 0x82 }, 212 { .reg = 0x020d, .val = 0x28 }, 213 { .reg = 0x020f, .val = 0x14 }, 214#endif 215 }; 216 217 static struct lg216x_reg lg2161_init[] = { 218 { .reg = 0x0000, .val = 0x41 }, 219 { .reg = 0x0001, .val = 0xfb }, 220 { .reg = 0x0216, .val = 0x00 }, 221 { .reg = 0x0219, .val = 0x00 }, 222 { .reg = 0x021b, .val = 0x55 }, 223 { .reg = 0x0606, .val = 0x0a }, 224 }; 225 226 switch (state->cfg->lg_chip) { 227 case LG2160: 228 ret = lg216x_write_regs(state, 229 lg2160_init, ARRAY_SIZE(lg2160_init)); 230 break; 231 case LG2161: 232 ret = lg216x_write_regs(state, 233 lg2161_init, ARRAY_SIZE(lg2161_init)); 234 break; 235 default: 236 ret = -EINVAL; 237 break; 238 } 239 if (lg_fail(ret)) 240 goto fail; 241 242 ret = lg216x_soft_reset(state); 243 lg_fail(ret); 244fail: 245 return ret; 246} 247 248/* ------------------------------------------------------------------------ */ 249 250static int lg216x_set_if(struct lg216x_state *state) 251{ 252 u8 val; 253 int ret; 254 255 lg_dbg("%d KHz\n", state->cfg->if_khz); 256 257 ret = lg216x_read_reg(state, 0x0132, &val); 258 if (lg_fail(ret)) 259 goto fail; 260 261 val &= 0xfb; 262 val |= (0 == state->cfg->if_khz) ? 0x04 : 0x00; 263 264 ret = lg216x_write_reg(state, 0x0132, val); 265 lg_fail(ret); 266 267 /* if NOT zero IF, 6 MHz is the default */ 268fail: 269 return ret; 270} 271 272/* ------------------------------------------------------------------------ */ 273 274static int lg2160_agc_fix(struct lg216x_state *state, 275 int if_agc_fix, int rf_agc_fix) 276{ 277 u8 val; 278 int ret; 279 280 ret = lg216x_read_reg(state, 0x0100, &val); 281 if (lg_fail(ret)) 282 goto fail; 283 284 val &= 0xf3; 285 val |= (if_agc_fix) ? 0x08 : 0x00; 286 val |= (rf_agc_fix) ? 0x04 : 0x00; 287 288 ret = lg216x_write_reg(state, 0x0100, val); 289 lg_fail(ret); 290fail: 291 return ret; 292} 293 294#if 0 295static int lg2160_agc_freeze(struct lg216x_state *state, 296 int if_agc_freeze, int rf_agc_freeze) 297{ 298 u8 val; 299 int ret; 300 301 ret = lg216x_read_reg(state, 0x0100, &val); 302 if (lg_fail(ret)) 303 goto fail; 304 305 val &= 0xcf; 306 val |= (if_agc_freeze) ? 0x20 : 0x00; 307 val |= (rf_agc_freeze) ? 0x10 : 0x00; 308 309 ret = lg216x_write_reg(state, 0x0100, val); 310 lg_fail(ret); 311fail: 312 return ret; 313} 314#endif 315 316static int lg2160_agc_polarity(struct lg216x_state *state, 317 int if_agc_polarity, int rf_agc_polarity) 318{ 319 u8 val; 320 int ret; 321 322 ret = lg216x_read_reg(state, 0x0100, &val); 323 if (lg_fail(ret)) 324 goto fail; 325 326 val &= 0xfc; 327 val |= (if_agc_polarity) ? 0x02 : 0x00; 328 val |= (rf_agc_polarity) ? 0x01 : 0x00; 329 330 ret = lg216x_write_reg(state, 0x0100, val); 331 lg_fail(ret); 332fail: 333 return ret; 334} 335 336static int lg2160_tuner_pwr_save_polarity(struct lg216x_state *state, 337 int polarity) 338{ 339 u8 val; 340 int ret; 341 342 ret = lg216x_read_reg(state, 0x0008, &val); 343 if (lg_fail(ret)) 344 goto fail; 345 346 val &= 0xfe; 347 val |= (polarity) ? 0x01 : 0x00; 348 349 ret = lg216x_write_reg(state, 0x0008, val); 350 lg_fail(ret); 351fail: 352 return ret; 353} 354 355static int lg2160_spectrum_polarity(struct lg216x_state *state, 356 int inverted) 357{ 358 u8 val; 359 int ret; 360 361 ret = lg216x_read_reg(state, 0x0132, &val); 362 if (lg_fail(ret)) 363 goto fail; 364 365 val &= 0xfd; 366 val |= (inverted) ? 0x02 : 0x00; 367 368 ret = lg216x_write_reg(state, 0x0132, val); 369 lg_fail(ret); 370fail: 371 return lg216x_soft_reset(state); 372} 373 374static int lg2160_tuner_pwr_save(struct lg216x_state *state, int onoff) 375{ 376 u8 val; 377 int ret; 378 379 ret = lg216x_read_reg(state, 0x0007, &val); 380 if (lg_fail(ret)) 381 goto fail; 382 383 val &= 0xbf; 384 val |= (onoff) ? 0x40 : 0x00; 385 386 ret = lg216x_write_reg(state, 0x0007, val); 387 lg_fail(ret); 388fail: 389 return ret; 390} 391 392static int lg216x_set_parade(struct lg216x_state *state, int id) 393{ 394 int ret; 395 396 ret = lg216x_write_reg(state, 0x013e, id & 0x7f); 397 if (lg_fail(ret)) 398 goto fail; 399 400 state->parade_id = id & 0x7f; 401fail: 402 return ret; 403} 404 405static int lg216x_set_ensemble(struct lg216x_state *state, int id) 406{ 407 int ret; 408 u16 reg; 409 u8 val; 410 411 switch (state->cfg->lg_chip) { 412 case LG2160: 413 reg = 0x0400; 414 break; 415 case LG2161: 416 default: 417 reg = 0x0500; 418 break; 419 } 420 421 ret = lg216x_read_reg(state, reg, &val); 422 if (lg_fail(ret)) 423 goto fail; 424 425 val &= 0xfe; 426 val |= (id) ? 0x01 : 0x00; 427 428 ret = lg216x_write_reg(state, reg, val); 429 lg_fail(ret); 430fail: 431 return ret; 432} 433 434static int lg2160_set_spi_clock(struct lg216x_state *state) 435{ 436 u8 val; 437 int ret; 438 439 ret = lg216x_read_reg(state, 0x0014, &val); 440 if (lg_fail(ret)) 441 goto fail; 442 443 val &= 0xf3; 444 val |= (state->cfg->spi_clock << 2); 445 446 ret = lg216x_write_reg(state, 0x0014, val); 447 lg_fail(ret); 448fail: 449 return ret; 450} 451 452static int lg2161_set_output_interface(struct lg216x_state *state) 453{ 454 u8 val; 455 int ret; 456 457 ret = lg216x_read_reg(state, 0x0014, &val); 458 if (lg_fail(ret)) 459 goto fail; 460 461 val &= ~0x07; 462 val |= state->cfg->output_if; /* FIXME: needs sanity check */ 463 464 ret = lg216x_write_reg(state, 0x0014, val); 465 lg_fail(ret); 466fail: 467 return ret; 468} 469 470static int lg216x_enable_fic(struct lg216x_state *state, int onoff) 471{ 472 int ret; 473 474 ret = lg216x_write_reg(state, 0x0017, 0x23); 475 if (lg_fail(ret)) 476 goto fail; 477 478 ret = lg216x_write_reg(state, 0x0016, 0xfc); 479 if (lg_fail(ret)) 480 goto fail; 481 482 switch (state->cfg->lg_chip) { 483 case LG2160: 484 ret = lg216x_write_reg(state, 0x0016, 485 0xfc | ((onoff) ? 0x02 : 0x00)); 486 break; 487 case LG2161: 488 ret = lg216x_write_reg(state, 0x0016, (onoff) ? 0x10 : 0x00); 489 break; 490 } 491 if (lg_fail(ret)) 492 goto fail; 493 494 ret = lg216x_initialize(state); 495 if (lg_fail(ret)) 496 goto fail; 497 498 if (onoff) { 499 ret = lg216x_write_reg(state, 0x0017, 0x03); 500 lg_fail(ret); 501 } 502fail: 503 return ret; 504} 505 506/* ------------------------------------------------------------------------ */ 507 508static int lg216x_get_fic_version(struct lg216x_state *state, u8 *ficver) 509{ 510 u8 val; 511 int ret; 512 513 *ficver = 0xff; /* invalid value */ 514 515 ret = lg216x_read_reg(state, 0x0128, &val); 516 if (lg_fail(ret)) 517 goto fail; 518 519 *ficver = (val >> 3) & 0x1f; 520fail: 521 return ret; 522} 523 524#if 0 525static int lg2160_get_parade_id(struct lg216x_state *state, u8 *id) 526{ 527 u8 val; 528 int ret; 529 530 *id = 0xff; /* invalid value */ 531 532 ret = lg216x_read_reg(state, 0x0123, &val); 533 if (lg_fail(ret)) 534 goto fail; 535 536 *id = val & 0x7f; 537fail: 538 return ret; 539} 540#endif 541 542static int lg216x_get_nog(struct lg216x_state *state, u8 *nog) 543{ 544 u8 val; 545 int ret; 546 547 *nog = 0xff; /* invalid value */ 548 549 ret = lg216x_read_reg(state, 0x0124, &val); 550 if (lg_fail(ret)) 551 goto fail; 552 553 *nog = ((val >> 4) & 0x07) + 1; 554fail: 555 return ret; 556} 557 558static int lg216x_get_tnog(struct lg216x_state *state, u8 *tnog) 559{ 560 u8 val; 561 int ret; 562 563 *tnog = 0xff; /* invalid value */ 564 565 ret = lg216x_read_reg(state, 0x0125, &val); 566 if (lg_fail(ret)) 567 goto fail; 568 569 *tnog = val & 0x1f; 570fail: 571 return ret; 572} 573 574static int lg216x_get_sgn(struct lg216x_state *state, u8 *sgn) 575{ 576 u8 val; 577 int ret; 578 579 *sgn = 0xff; /* invalid value */ 580 581 ret = lg216x_read_reg(state, 0x0124, &val); 582 if (lg_fail(ret)) 583 goto fail; 584 585 *sgn = val & 0x0f; 586fail: 587 return ret; 588} 589 590static int lg216x_get_prc(struct lg216x_state *state, u8 *prc) 591{ 592 u8 val; 593 int ret; 594 595 *prc = 0xff; /* invalid value */ 596 597 ret = lg216x_read_reg(state, 0x0125, &val); 598 if (lg_fail(ret)) 599 goto fail; 600 601 *prc = ((val >> 5) & 0x07) + 1; 602fail: 603 return ret; 604} 605 606/* ------------------------------------------------------------------------ */ 607 608static int lg216x_get_rs_frame_mode(struct lg216x_state *state, 609 enum atscmh_rs_frame_mode *rs_framemode) 610{ 611 u8 val; 612 int ret; 613 614 switch (state->cfg->lg_chip) { 615 case LG2160: 616 ret = lg216x_read_reg(state, 0x0410, &val); 617 break; 618 case LG2161: 619 ret = lg216x_read_reg(state, 0x0513, &val); 620 break; 621 default: 622 ret = -EINVAL; 623 } 624 if (lg_fail(ret)) 625 goto fail; 626 627 switch ((val >> 4) & 0x03) { 628#if 1 629 default: 630#endif 631 case 0x00: 632 *rs_framemode = ATSCMH_RSFRAME_PRI_ONLY; 633 break; 634 case 0x01: 635 *rs_framemode = ATSCMH_RSFRAME_PRI_SEC; 636 break; 637#if 0 638 default: 639 *rs_framemode = ATSCMH_RSFRAME_RES; 640 break; 641#endif 642 } 643fail: 644 return ret; 645} 646 647static 648int lg216x_get_rs_frame_ensemble(struct lg216x_state *state, 649 enum atscmh_rs_frame_ensemble *rs_frame_ens) 650{ 651 u8 val; 652 int ret; 653 654 switch (state->cfg->lg_chip) { 655 case LG2160: 656 ret = lg216x_read_reg(state, 0x0400, &val); 657 break; 658 case LG2161: 659 ret = lg216x_read_reg(state, 0x0500, &val); 660 break; 661 default: 662 ret = -EINVAL; 663 } 664 if (lg_fail(ret)) 665 goto fail; 666 667 val &= 0x01; 668 *rs_frame_ens = (enum atscmh_rs_frame_ensemble) val; 669fail: 670 return ret; 671} 672 673static int lg216x_get_rs_code_mode(struct lg216x_state *state, 674 enum atscmh_rs_code_mode *rs_code_pri, 675 enum atscmh_rs_code_mode *rs_code_sec) 676{ 677 u8 val; 678 int ret; 679 680 switch (state->cfg->lg_chip) { 681 case LG2160: 682 ret = lg216x_read_reg(state, 0x0410, &val); 683 break; 684 case LG2161: 685 ret = lg216x_read_reg(state, 0x0513, &val); 686 break; 687 default: 688 ret = -EINVAL; 689 } 690 if (lg_fail(ret)) 691 goto fail; 692 693 *rs_code_pri = (enum atscmh_rs_code_mode) ((val >> 2) & 0x03); 694 *rs_code_sec = (enum atscmh_rs_code_mode) (val & 0x03); 695fail: 696 return ret; 697} 698 699static int lg216x_get_sccc_block_mode(struct lg216x_state *state, 700 enum atscmh_sccc_block_mode *sccc_block) 701{ 702 u8 val; 703 int ret; 704 705 switch (state->cfg->lg_chip) { 706 case LG2160: 707 ret = lg216x_read_reg(state, 0x0315, &val); 708 break; 709 case LG2161: 710 ret = lg216x_read_reg(state, 0x0511, &val); 711 break; 712 default: 713 ret = -EINVAL; 714 } 715 if (lg_fail(ret)) 716 goto fail; 717 718 switch (val & 0x03) { 719 case 0x00: 720 *sccc_block = ATSCMH_SCCC_BLK_SEP; 721 break; 722 case 0x01: 723 *sccc_block = ATSCMH_SCCC_BLK_COMB; 724 break; 725 default: 726 *sccc_block = ATSCMH_SCCC_BLK_RES; 727 break; 728 } 729fail: 730 return ret; 731} 732 733static int lg216x_get_sccc_code_mode(struct lg216x_state *state, 734 enum atscmh_sccc_code_mode *mode_a, 735 enum atscmh_sccc_code_mode *mode_b, 736 enum atscmh_sccc_code_mode *mode_c, 737 enum atscmh_sccc_code_mode *mode_d) 738{ 739 u8 val; 740 int ret; 741 742 switch (state->cfg->lg_chip) { 743 case LG2160: 744 ret = lg216x_read_reg(state, 0x0316, &val); 745 break; 746 case LG2161: 747 ret = lg216x_read_reg(state, 0x0512, &val); 748 break; 749 default: 750 ret = -EINVAL; 751 } 752 if (lg_fail(ret)) 753 goto fail; 754 755 switch ((val >> 6) & 0x03) { 756 case 0x00: 757 *mode_a = ATSCMH_SCCC_CODE_HLF; 758 break; 759 case 0x01: 760 *mode_a = ATSCMH_SCCC_CODE_QTR; 761 break; 762 default: 763 *mode_a = ATSCMH_SCCC_CODE_RES; 764 break; 765 } 766 767 switch ((val >> 4) & 0x03) { 768 case 0x00: 769 *mode_b = ATSCMH_SCCC_CODE_HLF; 770 break; 771 case 0x01: 772 *mode_b = ATSCMH_SCCC_CODE_QTR; 773 break; 774 default: 775 *mode_b = ATSCMH_SCCC_CODE_RES; 776 break; 777 } 778 779 switch ((val >> 2) & 0x03) { 780 case 0x00: 781 *mode_c = ATSCMH_SCCC_CODE_HLF; 782 break; 783 case 0x01: 784 *mode_c = ATSCMH_SCCC_CODE_QTR; 785 break; 786 default: 787 *mode_c = ATSCMH_SCCC_CODE_RES; 788 break; 789 } 790 791 switch (val & 0x03) { 792 case 0x00: 793 *mode_d = ATSCMH_SCCC_CODE_HLF; 794 break; 795 case 0x01: 796 *mode_d = ATSCMH_SCCC_CODE_QTR; 797 break; 798 default: 799 *mode_d = ATSCMH_SCCC_CODE_RES; 800 break; 801 } 802fail: 803 return ret; 804} 805 806/* ------------------------------------------------------------------------ */ 807 808#if 0 809static int lg216x_read_fic_err_count(struct lg216x_state *state, u8 *err) 810{ 811 u8 fic_err; 812 int ret; 813 814 *err = 0; 815 816 switch (state->cfg->lg_chip) { 817 case LG2160: 818 ret = lg216x_read_reg(state, 0x0012, &fic_err); 819 break; 820 case LG2161: 821 ret = lg216x_read_reg(state, 0x001e, &fic_err); 822 break; 823 } 824 if (lg_fail(ret)) 825 goto fail; 826 827 *err = fic_err; 828fail: 829 return ret; 830} 831 832static int lg2160_read_crc_err_count(struct lg216x_state *state, u16 *err) 833{ 834 u8 crc_err1, crc_err2; 835 int ret; 836 837 *err = 0; 838 839 ret = lg216x_read_reg(state, 0x0411, &crc_err1); 840 if (lg_fail(ret)) 841 goto fail; 842 843 ret = lg216x_read_reg(state, 0x0412, &crc_err2); 844 if (lg_fail(ret)) 845 goto fail; 846 847 *err = (u16)(((crc_err2 & 0x0f) << 8) | crc_err1); 848fail: 849 return ret; 850} 851 852static int lg2161_read_crc_err_count(struct lg216x_state *state, u16 *err) 853{ 854 u8 crc_err; 855 int ret; 856 857 *err = 0; 858 859 ret = lg216x_read_reg(state, 0x0612, &crc_err); 860 if (lg_fail(ret)) 861 goto fail; 862 863 *err = (u16)crc_err; 864fail: 865 return ret; 866} 867 868static int lg216x_read_crc_err_count(struct lg216x_state *state, u16 *err) 869{ 870 int ret; 871 switch (state->cfg->lg_chip) { 872 case LG2160: 873 ret = lg2160_read_crc_err_count(state, err); 874 break; 875 case LG2161: 876 ret = lg2161_read_crc_err_count(state, err); 877 break; 878 default: 879 ret = -EINVAL; 880 break; 881 } 882 return ret; 883} 884 885static int lg2160_read_rs_err_count(struct lg216x_state *state, u16 *err) 886{ 887 u8 rs_err1, rs_err2; 888 int ret; 889 890 *err = 0; 891 892 ret = lg216x_read_reg(state, 0x0413, &rs_err1); 893 if (lg_fail(ret)) 894 goto fail; 895 896 ret = lg216x_read_reg(state, 0x0414, &rs_err2); 897 if (lg_fail(ret)) 898 goto fail; 899 900 *err = (u16)(((rs_err2 & 0x0f) << 8) | rs_err1); 901fail: 902 return ret; 903} 904 905static int lg2161_read_rs_err_count(struct lg216x_state *state, u16 *err) 906{ 907 u8 rs_err1, rs_err2; 908 int ret; 909 910 *err = 0; 911 912 ret = lg216x_read_reg(state, 0x0613, &rs_err1); 913 if (lg_fail(ret)) 914 goto fail; 915 916 ret = lg216x_read_reg(state, 0x0614, &rs_err2); 917 if (lg_fail(ret)) 918 goto fail; 919 920 *err = (u16)((rs_err1 << 8) | rs_err2); 921fail: 922 return ret; 923} 924 925static int lg216x_read_rs_err_count(struct lg216x_state *state, u16 *err) 926{ 927 int ret; 928 switch (state->cfg->lg_chip) { 929 case LG2160: 930 ret = lg2160_read_rs_err_count(state, err); 931 break; 932 case LG2161: 933 ret = lg2161_read_rs_err_count(state, err); 934 break; 935 default: 936 ret = -EINVAL; 937 break; 938 } 939 return ret; 940} 941#endif 942 943/* ------------------------------------------------------------------------ */ 944 945static int lg216x_get_frontend(struct dvb_frontend *fe) 946{ 947 struct lg216x_state *state = fe->demodulator_priv; 948 int ret; 949 950 lg_dbg("\n"); 951 952 fe->dtv_property_cache.modulation = VSB_8; 953 fe->dtv_property_cache.frequency = state->current_frequency; 954 fe->dtv_property_cache.delivery_system = SYS_ATSCMH; 955 956 ret = lg216x_get_fic_version(state, 957 &fe->dtv_property_cache.atscmh_fic_ver); 958 if (lg_fail(ret)) 959 goto fail; 960 if (state->fic_ver != fe->dtv_property_cache.atscmh_fic_ver) { 961 state->fic_ver = fe->dtv_property_cache.atscmh_fic_ver; 962 963#if 0 964 ret = lg2160_get_parade_id(state, 965 &fe->dtv_property_cache.atscmh_parade_id); 966 if (lg_fail(ret)) 967 goto fail; 968/* #else */ 969 fe->dtv_property_cache.atscmh_parade_id = state->parade_id; 970#endif 971 ret = lg216x_get_nog(state, 972 &fe->dtv_property_cache.atscmh_nog); 973 if (lg_fail(ret)) 974 goto fail; 975 ret = lg216x_get_tnog(state, 976 &fe->dtv_property_cache.atscmh_tnog); 977 if (lg_fail(ret)) 978 goto fail; 979 ret = lg216x_get_sgn(state, 980 &fe->dtv_property_cache.atscmh_sgn); 981 if (lg_fail(ret)) 982 goto fail; 983 ret = lg216x_get_prc(state, 984 &fe->dtv_property_cache.atscmh_prc); 985 if (lg_fail(ret)) 986 goto fail; 987 988 ret = lg216x_get_rs_frame_mode(state, 989 (enum atscmh_rs_frame_mode *) 990 &fe->dtv_property_cache.atscmh_rs_frame_mode); 991 if (lg_fail(ret)) 992 goto fail; 993 ret = lg216x_get_rs_frame_ensemble(state, 994 (enum atscmh_rs_frame_ensemble *) 995 &fe->dtv_property_cache.atscmh_rs_frame_ensemble); 996 if (lg_fail(ret)) 997 goto fail; 998 ret = lg216x_get_rs_code_mode(state, 999 (enum atscmh_rs_code_mode *) 1000 &fe->dtv_property_cache.atscmh_rs_code_mode_pri, 1001 (enum atscmh_rs_code_mode *) 1002 &fe->dtv_property_cache.atscmh_rs_code_mode_sec); 1003 if (lg_fail(ret)) 1004 goto fail; 1005 ret = lg216x_get_sccc_block_mode(state, 1006 (enum atscmh_sccc_block_mode *) 1007 &fe->dtv_property_cache.atscmh_sccc_block_mode); 1008 if (lg_fail(ret)) 1009 goto fail; 1010 ret = lg216x_get_sccc_code_mode(state, 1011 (enum atscmh_sccc_code_mode *) 1012 &fe->dtv_property_cache.atscmh_sccc_code_mode_a, 1013 (enum atscmh_sccc_code_mode *) 1014 &fe->dtv_property_cache.atscmh_sccc_code_mode_b, 1015 (enum atscmh_sccc_code_mode *) 1016 &fe->dtv_property_cache.atscmh_sccc_code_mode_c, 1017 (enum atscmh_sccc_code_mode *) 1018 &fe->dtv_property_cache.atscmh_sccc_code_mode_d); 1019 if (lg_fail(ret)) 1020 goto fail; 1021 } 1022#if 0 1023 ret = lg216x_read_fic_err_count(state, 1024 (u8 *)&fe->dtv_property_cache.atscmh_fic_err); 1025 if (lg_fail(ret)) 1026 goto fail; 1027 ret = lg216x_read_crc_err_count(state, 1028 &fe->dtv_property_cache.atscmh_crc_err); 1029 if (lg_fail(ret)) 1030 goto fail; 1031 ret = lg216x_read_rs_err_count(state, 1032 &fe->dtv_property_cache.atscmh_rs_err); 1033 if (lg_fail(ret)) 1034 goto fail; 1035 1036 switch (state->cfg->lg_chip) { 1037 case LG2160: 1038 if (((fe->dtv_property_cache.atscmh_rs_err >= 240) && 1039 (fe->dtv_property_cache.atscmh_crc_err >= 240)) && 1040 ((jiffies_to_msecs(jiffies) - state->last_reset) > 6000)) 1041 ret = lg216x_soft_reset(state); 1042 break; 1043 case LG2161: 1044 /* no fix needed here (as far as we know) */ 1045 ret = 0; 1046 break; 1047 } 1048 lg_fail(ret); 1049#endif 1050fail: 1051 return ret; 1052} 1053 1054static int lg216x_get_property(struct dvb_frontend *fe, 1055 struct dtv_property *tvp) 1056{ 1057 return (DTV_ATSCMH_FIC_VER == tvp->cmd) ? 1058 lg216x_get_frontend(fe) : 0; 1059} 1060 1061 1062static int lg2160_set_frontend(struct dvb_frontend *fe) 1063{ 1064 struct lg216x_state *state = fe->demodulator_priv; 1065 int ret; 1066 1067 lg_dbg("(%d)\n", fe->dtv_property_cache.frequency); 1068 1069 if (fe->ops.tuner_ops.set_params) { 1070 ret = fe->ops.tuner_ops.set_params(fe); 1071 if (fe->ops.i2c_gate_ctrl) 1072 fe->ops.i2c_gate_ctrl(fe, 0); 1073 if (lg_fail(ret)) 1074 goto fail; 1075 state->current_frequency = fe->dtv_property_cache.frequency; 1076 } 1077 1078 ret = lg2160_agc_fix(state, 0, 0); 1079 if (lg_fail(ret)) 1080 goto fail; 1081 ret = lg2160_agc_polarity(state, 0, 0); 1082 if (lg_fail(ret)) 1083 goto fail; 1084 ret = lg2160_tuner_pwr_save_polarity(state, 1); 1085 if (lg_fail(ret)) 1086 goto fail; 1087 ret = lg216x_set_if(state); 1088 if (lg_fail(ret)) 1089 goto fail; 1090 ret = lg2160_spectrum_polarity(state, state->cfg->spectral_inversion); 1091 if (lg_fail(ret)) 1092 goto fail; 1093 1094 /* be tuned before this point */ 1095 ret = lg216x_soft_reset(state); 1096 if (lg_fail(ret)) 1097 goto fail; 1098 1099 ret = lg2160_tuner_pwr_save(state, 0); 1100 if (lg_fail(ret)) 1101 goto fail; 1102 1103 switch (state->cfg->lg_chip) { 1104 case LG2160: 1105 ret = lg2160_set_spi_clock(state); 1106 if (lg_fail(ret)) 1107 goto fail; 1108 break; 1109 case LG2161: 1110 ret = lg2161_set_output_interface(state); 1111 if (lg_fail(ret)) 1112 goto fail; 1113 break; 1114 } 1115 1116 ret = lg216x_set_parade(state, fe->dtv_property_cache.atscmh_parade_id); 1117 if (lg_fail(ret)) 1118 goto fail; 1119 1120 ret = lg216x_set_ensemble(state, 1121 fe->dtv_property_cache.atscmh_rs_frame_ensemble); 1122 if (lg_fail(ret)) 1123 goto fail; 1124 1125 ret = lg216x_initialize(state); 1126 if (lg_fail(ret)) 1127 goto fail; 1128 1129 ret = lg216x_enable_fic(state, 1); 1130 lg_fail(ret); 1131 1132 lg216x_get_frontend(fe); 1133fail: 1134 return ret; 1135} 1136 1137/* ------------------------------------------------------------------------ */ 1138 1139static int lg2160_read_lock_status(struct lg216x_state *state, 1140 int *acq_lock, int *sync_lock) 1141{ 1142 u8 val; 1143 int ret; 1144 1145 *acq_lock = 0; 1146 *sync_lock = 0; 1147 1148 ret = lg216x_read_reg(state, 0x011b, &val); 1149 if (lg_fail(ret)) 1150 goto fail; 1151 1152 *sync_lock = (val & 0x20) ? 0 : 1; 1153 *acq_lock = (val & 0x40) ? 0 : 1; 1154fail: 1155 return ret; 1156} 1157 1158#ifdef USE_LG2161_LOCK_BITS 1159static int lg2161_read_lock_status(struct lg216x_state *state, 1160 int *acq_lock, int *sync_lock) 1161{ 1162 u8 val; 1163 int ret; 1164 1165 *acq_lock = 0; 1166 *sync_lock = 0; 1167 1168 ret = lg216x_read_reg(state, 0x0304, &val); 1169 if (lg_fail(ret)) 1170 goto fail; 1171 1172 *sync_lock = (val & 0x80) ? 0 : 1; 1173 1174 ret = lg216x_read_reg(state, 0x011b, &val); 1175 if (lg_fail(ret)) 1176 goto fail; 1177 1178 *acq_lock = (val & 0x40) ? 0 : 1; 1179fail: 1180 return ret; 1181} 1182#endif 1183 1184static int lg216x_read_lock_status(struct lg216x_state *state, 1185 int *acq_lock, int *sync_lock) 1186{ 1187#ifdef USE_LG2161_LOCK_BITS 1188 int ret; 1189 switch (state->cfg->lg_chip) { 1190 case LG2160: 1191 ret = lg2160_read_lock_status(state, acq_lock, sync_lock); 1192 break; 1193 case LG2161: 1194 ret = lg2161_read_lock_status(state, acq_lock, sync_lock); 1195 break; 1196 default: 1197 ret = -EINVAL; 1198 break; 1199 } 1200 return ret; 1201#else 1202 return lg2160_read_lock_status(state, acq_lock, sync_lock); 1203#endif 1204} 1205 1206static int lg216x_read_status(struct dvb_frontend *fe, enum fe_status *status) 1207{ 1208 struct lg216x_state *state = fe->demodulator_priv; 1209 int ret, acq_lock, sync_lock; 1210 1211 *status = 0; 1212 1213 ret = lg216x_read_lock_status(state, &acq_lock, &sync_lock); 1214 if (lg_fail(ret)) 1215 goto fail; 1216 1217 lg_dbg("%s%s\n", 1218 acq_lock ? "SIGNALEXIST " : "", 1219 sync_lock ? "SYNCLOCK" : ""); 1220 1221 if (acq_lock) 1222 *status |= FE_HAS_SIGNAL; 1223 if (sync_lock) 1224 *status |= FE_HAS_SYNC; 1225 1226 if (*status) 1227 *status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK; 1228 1229fail: 1230 return ret; 1231} 1232 1233/* ------------------------------------------------------------------------ */ 1234 1235static int lg2160_read_snr(struct dvb_frontend *fe, u16 *snr) 1236{ 1237 struct lg216x_state *state = fe->demodulator_priv; 1238 u8 snr1, snr2; 1239 int ret; 1240 1241 *snr = 0; 1242 1243 ret = lg216x_read_reg(state, 0x0202, &snr1); 1244 if (lg_fail(ret)) 1245 goto fail; 1246 1247 ret = lg216x_read_reg(state, 0x0203, &snr2); 1248 if (lg_fail(ret)) 1249 goto fail; 1250 1251 if ((snr1 == 0xba) || (snr2 == 0xdf)) 1252 *snr = 0; 1253 else 1254#if 1 1255 *snr = ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 >> 4); 1256#else /* BCD */ 1257 *snr = (snr2 | (snr1 << 8)); 1258#endif 1259fail: 1260 return ret; 1261} 1262 1263static int lg2161_read_snr(struct dvb_frontend *fe, u16 *snr) 1264{ 1265 struct lg216x_state *state = fe->demodulator_priv; 1266 u8 snr1, snr2; 1267 int ret; 1268 1269 *snr = 0; 1270 1271 ret = lg216x_read_reg(state, 0x0302, &snr1); 1272 if (lg_fail(ret)) 1273 goto fail; 1274 1275 ret = lg216x_read_reg(state, 0x0303, &snr2); 1276 if (lg_fail(ret)) 1277 goto fail; 1278 1279 if ((snr1 == 0xba) || (snr2 == 0xfd)) 1280 *snr = 0; 1281 else 1282 1283 *snr = ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 & 0x0f); 1284fail: 1285 return ret; 1286} 1287 1288static int lg216x_read_signal_strength(struct dvb_frontend *fe, 1289 u16 *strength) 1290{ 1291#if 0 1292 /* borrowed from lgdt330x.c 1293 * 1294 * Calculate strength from SNR up to 35dB 1295 * Even though the SNR can go higher than 35dB, 1296 * there is some comfort factor in having a range of 1297 * strong signals that can show at 100% 1298 */ 1299 struct lg216x_state *state = fe->demodulator_priv; 1300 u16 snr; 1301 int ret; 1302#endif 1303 *strength = 0; 1304#if 0 1305 ret = fe->ops.read_snr(fe, &snr); 1306 if (lg_fail(ret)) 1307 goto fail; 1308 /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ 1309 /* scale the range 0 - 35*2^24 into 0 - 65535 */ 1310 if (state->snr >= 8960 * 0x10000) 1311 *strength = 0xffff; 1312 else 1313 *strength = state->snr / 8960; 1314fail: 1315 return ret; 1316#else 1317 return 0; 1318#endif 1319} 1320 1321/* ------------------------------------------------------------------------ */ 1322 1323static int lg216x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 1324{ 1325#if 0 1326 struct lg216x_state *state = fe->demodulator_priv; 1327 int ret; 1328 1329 ret = lg216x_read_rs_err_count(state, 1330 &fe->dtv_property_cache.atscmh_rs_err); 1331 if (lg_fail(ret)) 1332 goto fail; 1333 1334 *ucblocks = fe->dtv_property_cache.atscmh_rs_err; 1335fail: 1336#else 1337 *ucblocks = 0; 1338#endif 1339 return 0; 1340} 1341 1342static int lg216x_get_tune_settings(struct dvb_frontend *fe, 1343 struct dvb_frontend_tune_settings 1344 *fe_tune_settings) 1345{ 1346 fe_tune_settings->min_delay_ms = 500; 1347 lg_dbg("\n"); 1348 return 0; 1349} 1350 1351static void lg216x_release(struct dvb_frontend *fe) 1352{ 1353 struct lg216x_state *state = fe->demodulator_priv; 1354 lg_dbg("\n"); 1355 kfree(state); 1356} 1357 1358static struct dvb_frontend_ops lg2160_ops = { 1359 .delsys = { SYS_ATSCMH }, 1360 .info = { 1361 .name = "LG Electronics LG2160 ATSC/MH Frontend", 1362 .frequency_min = 54000000, 1363 .frequency_max = 858000000, 1364 .frequency_stepsize = 62500, 1365 }, 1366 .i2c_gate_ctrl = lg216x_i2c_gate_ctrl, 1367#if 0 1368 .init = lg216x_init, 1369 .sleep = lg216x_sleep, 1370#endif 1371 .get_property = lg216x_get_property, 1372 1373 .set_frontend = lg2160_set_frontend, 1374 .get_frontend = lg216x_get_frontend, 1375 .get_tune_settings = lg216x_get_tune_settings, 1376 .read_status = lg216x_read_status, 1377#if 0 1378 .read_ber = lg216x_read_ber, 1379#endif 1380 .read_signal_strength = lg216x_read_signal_strength, 1381 .read_snr = lg2160_read_snr, 1382 .read_ucblocks = lg216x_read_ucblocks, 1383 .release = lg216x_release, 1384}; 1385 1386static struct dvb_frontend_ops lg2161_ops = { 1387 .delsys = { SYS_ATSCMH }, 1388 .info = { 1389 .name = "LG Electronics LG2161 ATSC/MH Frontend", 1390 .frequency_min = 54000000, 1391 .frequency_max = 858000000, 1392 .frequency_stepsize = 62500, 1393 }, 1394 .i2c_gate_ctrl = lg216x_i2c_gate_ctrl, 1395#if 0 1396 .init = lg216x_init, 1397 .sleep = lg216x_sleep, 1398#endif 1399 .get_property = lg216x_get_property, 1400 1401 .set_frontend = lg2160_set_frontend, 1402 .get_frontend = lg216x_get_frontend, 1403 .get_tune_settings = lg216x_get_tune_settings, 1404 .read_status = lg216x_read_status, 1405#if 0 1406 .read_ber = lg216x_read_ber, 1407#endif 1408 .read_signal_strength = lg216x_read_signal_strength, 1409 .read_snr = lg2161_read_snr, 1410 .read_ucblocks = lg216x_read_ucblocks, 1411 .release = lg216x_release, 1412}; 1413 1414struct dvb_frontend *lg2160_attach(const struct lg2160_config *config, 1415 struct i2c_adapter *i2c_adap) 1416{ 1417 struct lg216x_state *state = NULL; 1418 1419 lg_dbg("(%d-%04x)\n", 1420 i2c_adap ? i2c_adapter_id(i2c_adap) : 0, 1421 config ? config->i2c_addr : 0); 1422 1423 state = kzalloc(sizeof(struct lg216x_state), GFP_KERNEL); 1424 if (!state) 1425 return NULL; 1426 1427 state->cfg = config; 1428 state->i2c_adap = i2c_adap; 1429 state->fic_ver = 0xff; 1430 state->parade_id = 0xff; 1431 1432 switch (config->lg_chip) { 1433 default: 1434 lg_warn("invalid chip requested, defaulting to LG2160"); 1435 /* fall-thru */ 1436 case LG2160: 1437 memcpy(&state->frontend.ops, &lg2160_ops, 1438 sizeof(struct dvb_frontend_ops)); 1439 break; 1440 case LG2161: 1441 memcpy(&state->frontend.ops, &lg2161_ops, 1442 sizeof(struct dvb_frontend_ops)); 1443 break; 1444 } 1445 1446 state->frontend.demodulator_priv = state; 1447 state->current_frequency = -1; 1448 /* parade 1 by default */ 1449 state->frontend.dtv_property_cache.atscmh_parade_id = 1; 1450 1451 return &state->frontend; 1452} 1453EXPORT_SYMBOL(lg2160_attach); 1454 1455MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver"); 1456MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); 1457MODULE_LICENSE("GPL"); 1458MODULE_VERSION("0.3"); 1459