1 /* 2 * Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator 3 * LGS8913, LGS8GL5, LGS8G75 4 * experimental support LGS8G42, LGS8G52 5 * 6 * Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com> 7 * Copyright (C) 2008 Sirius International (Hong Kong) Limited 8 * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5) 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 * 24 */ 25 26 #include <asm/div64.h> 27 #include <linux/firmware.h> 28 29 #include "dvb_frontend.h" 30 31 #include "lgs8gxx.h" 32 #include "lgs8gxx_priv.h" 33 34 #define dprintk(args...) \ 35 do { \ 36 if (debug) \ 37 printk(KERN_DEBUG "lgs8gxx: " args); \ 38 } while (0) 39 40 static int debug; 41 static int fake_signal_str = 1; 42 43 #define LGS8GXX_FIRMWARE "lgs8g75.fw" 44 45 module_param(debug, int, 0644); 46 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 47 48 module_param(fake_signal_str, int, 0644); 49 MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913." 50 "Signal strength calculation is slow.(default:on)."); 51 52 /* LGS8GXX internal helper functions */ 53 54 static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data) 55 { 56 int ret; 57 u8 buf[] = { reg, data }; 58 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; 59 60 msg.addr = priv->config->demod_address; 61 if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0) 62 msg.addr += 0x02; 63 64 if (debug >= 2) 65 dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data); 66 67 ret = i2c_transfer(priv->i2c, &msg, 1); 68 69 if (ret != 1) 70 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n", 71 __func__, reg, data, ret); 72 73 return (ret != 1) ? -1 : 0; 74 } 75 76 static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data) 77 { 78 int ret; 79 u8 dev_addr; 80 81 u8 b0[] = { reg }; 82 u8 b1[] = { 0 }; 83 struct i2c_msg msg[] = { 84 { .flags = 0, .buf = b0, .len = 1 }, 85 { .flags = I2C_M_RD, .buf = b1, .len = 1 }, 86 }; 87 88 dev_addr = priv->config->demod_address; 89 if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0) 90 dev_addr += 0x02; 91 msg[1].addr = msg[0].addr = dev_addr; 92 93 ret = i2c_transfer(priv->i2c, msg, 2); 94 if (ret != 2) { 95 dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret); 96 return -1; 97 } 98 99 *p_data = b1[0]; 100 if (debug >= 2) 101 dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, b1[0]); 102 return 0; 103 } 104 105 static int lgs8gxx_soft_reset(struct lgs8gxx_state *priv) 106 { 107 lgs8gxx_write_reg(priv, 0x02, 0x00); 108 msleep(1); 109 lgs8gxx_write_reg(priv, 0x02, 0x01); 110 msleep(100); 111 112 return 0; 113 } 114 115 static int wait_reg_mask(struct lgs8gxx_state *priv, u8 reg, u8 mask, 116 u8 val, u8 delay, u8 tries) 117 { 118 u8 t; 119 int i; 120 121 for (i = 0; i < tries; i++) { 122 lgs8gxx_read_reg(priv, reg, &t); 123 124 if ((t & mask) == val) 125 return 0; 126 msleep(delay); 127 } 128 129 return 1; 130 } 131 132 static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv) 133 { 134 const struct lgs8gxx_config *config = priv->config; 135 u8 if_conf; 136 137 if_conf = 0x10; /* AGC output on, RF_AGC output off; */ 138 139 if_conf |= 140 ((config->ext_adc) ? 0x80 : 0x00) | 141 ((config->if_neg_center) ? 0x04 : 0x00) | 142 ((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */ 143 ((config->adc_signed) ? 0x02 : 0x00) | 144 ((config->if_neg_edge) ? 0x01 : 0x00); 145 146 if (config->ext_adc && 147 (config->prod == LGS8GXX_PROD_LGS8G52)) { 148 lgs8gxx_write_reg(priv, 0xBA, 0x40); 149 } 150 151 lgs8gxx_write_reg(priv, 0x07, if_conf); 152 153 return 0; 154 } 155 156 static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/) 157 { 158 u64 val; 159 u32 v32; 160 u32 if_clk; 161 162 if_clk = priv->config->if_clk_freq; 163 164 val = freq; 165 if (freq != 0) { 166 val <<= 32; 167 if (if_clk != 0) 168 do_div(val, if_clk); 169 v32 = val & 0xFFFFFFFF; 170 dprintk("Set IF Freq to %dkHz\n", freq); 171 } else { 172 v32 = 0; 173 dprintk("Set IF Freq to baseband\n"); 174 } 175 dprintk("AFC_INIT_FREQ = 0x%08X\n", v32); 176 177 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 178 lgs8gxx_write_reg(priv, 0x08, 0xFF & (v32)); 179 lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32 >> 8)); 180 lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 16)); 181 lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 24)); 182 } else { 183 lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32)); 184 lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8)); 185 lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16)); 186 lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24)); 187 } 188 189 return 0; 190 } 191 192 static int lgs8gxx_get_afc_phase(struct lgs8gxx_state *priv) 193 { 194 u64 val; 195 u32 v32 = 0; 196 u8 reg_addr, t; 197 int i; 198 199 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) 200 reg_addr = 0x23; 201 else 202 reg_addr = 0x48; 203 204 for (i = 0; i < 4; i++) { 205 lgs8gxx_read_reg(priv, reg_addr, &t); 206 v32 <<= 8; 207 v32 |= t; 208 reg_addr--; 209 } 210 211 val = v32; 212 val *= priv->config->if_clk_freq; 213 val >>= 32; 214 dprintk("AFC = %u kHz\n", (u32)val); 215 return 0; 216 } 217 218 static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv) 219 { 220 u8 t; 221 u8 prod = priv->config->prod; 222 223 if (prod == LGS8GXX_PROD_LGS8913) 224 lgs8gxx_write_reg(priv, 0xC6, 0x01); 225 226 if (prod == LGS8GXX_PROD_LGS8G75) { 227 lgs8gxx_read_reg(priv, 0x0C, &t); 228 t &= (~0x04); 229 lgs8gxx_write_reg(priv, 0x0C, t | 0x80); 230 lgs8gxx_write_reg(priv, 0x39, 0x00); 231 lgs8gxx_write_reg(priv, 0x3D, 0x04); 232 } else if (prod == LGS8GXX_PROD_LGS8913 || 233 prod == LGS8GXX_PROD_LGS8GL5 || 234 prod == LGS8GXX_PROD_LGS8G42 || 235 prod == LGS8GXX_PROD_LGS8G52 || 236 prod == LGS8GXX_PROD_LGS8G54) { 237 lgs8gxx_read_reg(priv, 0x7E, &t); 238 lgs8gxx_write_reg(priv, 0x7E, t | 0x01); 239 240 /* clear FEC self reset */ 241 lgs8gxx_read_reg(priv, 0xC5, &t); 242 lgs8gxx_write_reg(priv, 0xC5, t & 0xE0); 243 } 244 245 if (prod == LGS8GXX_PROD_LGS8913) { 246 /* FEC auto detect */ 247 lgs8gxx_write_reg(priv, 0xC1, 0x03); 248 249 lgs8gxx_read_reg(priv, 0x7C, &t); 250 t = (t & 0x8C) | 0x03; 251 lgs8gxx_write_reg(priv, 0x7C, t); 252 253 /* BER test mode */ 254 lgs8gxx_read_reg(priv, 0xC3, &t); 255 t = (t & 0xEF) | 0x10; 256 lgs8gxx_write_reg(priv, 0xC3, t); 257 } 258 259 if (priv->config->prod == LGS8GXX_PROD_LGS8G52) 260 lgs8gxx_write_reg(priv, 0xD9, 0x40); 261 262 return 0; 263 } 264 265 static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv) 266 { 267 u8 t; 268 269 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 270 u8 t2; 271 lgs8gxx_read_reg(priv, 0x0C, &t); 272 t &= (~0x80); 273 lgs8gxx_write_reg(priv, 0x0C, t); 274 275 lgs8gxx_read_reg(priv, 0x0C, &t); 276 lgs8gxx_read_reg(priv, 0x19, &t2); 277 278 if (((t&0x03) == 0x01) && (t2&0x01)) { 279 lgs8gxx_write_reg(priv, 0x6E, 0x05); 280 lgs8gxx_write_reg(priv, 0x39, 0x02); 281 lgs8gxx_write_reg(priv, 0x39, 0x03); 282 lgs8gxx_write_reg(priv, 0x3D, 0x05); 283 lgs8gxx_write_reg(priv, 0x3E, 0x28); 284 lgs8gxx_write_reg(priv, 0x53, 0x80); 285 } else { 286 lgs8gxx_write_reg(priv, 0x6E, 0x3F); 287 lgs8gxx_write_reg(priv, 0x39, 0x00); 288 lgs8gxx_write_reg(priv, 0x3D, 0x04); 289 } 290 291 lgs8gxx_soft_reset(priv); 292 return 0; 293 } 294 295 /* turn off auto-detect; manual settings */ 296 lgs8gxx_write_reg(priv, 0x7E, 0); 297 if (priv->config->prod == LGS8GXX_PROD_LGS8913) 298 lgs8gxx_write_reg(priv, 0xC1, 0); 299 300 lgs8gxx_read_reg(priv, 0xC5, &t); 301 t = (t & 0xE0) | 0x06; 302 lgs8gxx_write_reg(priv, 0xC5, t); 303 304 lgs8gxx_soft_reset(priv); 305 306 return 0; 307 } 308 309 static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked) 310 { 311 int ret = 0; 312 u8 t; 313 314 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) 315 ret = lgs8gxx_read_reg(priv, 0x13, &t); 316 else 317 ret = lgs8gxx_read_reg(priv, 0x4B, &t); 318 if (ret != 0) 319 return ret; 320 321 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) 322 *locked = ((t & 0x80) == 0x80) ? 1 : 0; 323 else 324 *locked = ((t & 0xC0) == 0xC0) ? 1 : 0; 325 return 0; 326 } 327 328 /* Wait for Code Acquisition Lock */ 329 static int lgs8gxx_wait_ca_lock(struct lgs8gxx_state *priv, u8 *locked) 330 { 331 int ret = 0; 332 u8 reg, mask, val; 333 334 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 335 reg = 0x13; 336 mask = 0x80; 337 val = 0x80; 338 } else { 339 reg = 0x4B; 340 mask = 0xC0; 341 val = 0xC0; 342 } 343 344 ret = wait_reg_mask(priv, reg, mask, val, 50, 40); 345 *locked = (ret == 0) ? 1 : 0; 346 347 return 0; 348 } 349 350 static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv, 351 u8 *finished) 352 { 353 int ret = 0; 354 u8 reg, mask, val; 355 356 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 357 reg = 0x1f; 358 mask = 0xC0; 359 val = 0x80; 360 } else { 361 reg = 0xA4; 362 mask = 0x03; 363 val = 0x01; 364 } 365 366 ret = wait_reg_mask(priv, reg, mask, val, 10, 20); 367 *finished = (ret == 0) ? 1 : 0; 368 369 return 0; 370 } 371 372 static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 cpn, 373 u8 *locked) 374 { 375 int err = 0; 376 u8 ad_fini = 0; 377 u8 t1, t2; 378 379 if (gi == GI_945) 380 dprintk("try GI 945\n"); 381 else if (gi == GI_595) 382 dprintk("try GI 595\n"); 383 else if (gi == GI_420) 384 dprintk("try GI 420\n"); 385 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 386 lgs8gxx_read_reg(priv, 0x0C, &t1); 387 lgs8gxx_read_reg(priv, 0x18, &t2); 388 t1 &= ~(GI_MASK); 389 t1 |= gi; 390 t2 &= 0xFE; 391 t2 |= cpn ? 0x01 : 0x00; 392 lgs8gxx_write_reg(priv, 0x0C, t1); 393 lgs8gxx_write_reg(priv, 0x18, t2); 394 } else { 395 lgs8gxx_write_reg(priv, 0x04, gi); 396 } 397 lgs8gxx_soft_reset(priv); 398 err = lgs8gxx_wait_ca_lock(priv, locked); 399 if (err || !(*locked)) 400 return err; 401 err = lgs8gxx_is_autodetect_finished(priv, &ad_fini); 402 if (err != 0) 403 return err; 404 if (ad_fini) { 405 dprintk("auto detect finished\n"); 406 } else 407 *locked = 0; 408 409 return 0; 410 } 411 412 static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv, 413 u8 *detected_param, u8 *gi) 414 { 415 int i, j; 416 int err = 0; 417 u8 locked = 0, tmp_gi; 418 419 dprintk("%s\n", __func__); 420 421 lgs8gxx_set_mode_auto(priv); 422 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 423 lgs8gxx_write_reg(priv, 0x67, 0xAA); 424 lgs8gxx_write_reg(priv, 0x6E, 0x3F); 425 } else { 426 /* Guard Interval */ 427 lgs8gxx_write_reg(priv, 0x03, 00); 428 } 429 430 for (i = 0; i < 2; i++) { 431 for (j = 0; j < 2; j++) { 432 tmp_gi = GI_945; 433 err = lgs8gxx_autolock_gi(priv, GI_945, j, &locked); 434 if (err) 435 goto out; 436 if (locked) 437 goto locked; 438 } 439 for (j = 0; j < 2; j++) { 440 tmp_gi = GI_420; 441 err = lgs8gxx_autolock_gi(priv, GI_420, j, &locked); 442 if (err) 443 goto out; 444 if (locked) 445 goto locked; 446 } 447 tmp_gi = GI_595; 448 err = lgs8gxx_autolock_gi(priv, GI_595, 1, &locked); 449 if (err) 450 goto out; 451 if (locked) 452 goto locked; 453 } 454 455 locked: 456 if ((err == 0) && (locked == 1)) { 457 u8 t; 458 459 if (priv->config->prod != LGS8GXX_PROD_LGS8G75) { 460 lgs8gxx_read_reg(priv, 0xA2, &t); 461 *detected_param = t; 462 } else { 463 lgs8gxx_read_reg(priv, 0x1F, &t); 464 *detected_param = t & 0x3F; 465 } 466 467 if (tmp_gi == GI_945) 468 dprintk("GI 945 locked\n"); 469 else if (tmp_gi == GI_595) 470 dprintk("GI 595 locked\n"); 471 else if (tmp_gi == GI_420) 472 dprintk("GI 420 locked\n"); 473 *gi = tmp_gi; 474 } 475 if (!locked) 476 err = -1; 477 478 out: 479 return err; 480 } 481 482 static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv) 483 { 484 s8 err; 485 u8 gi = 0x2; 486 u8 detected_param = 0; 487 488 err = lgs8gxx_auto_detect(priv, &detected_param, &gi); 489 490 if (err != 0) { 491 dprintk("lgs8gxx_auto_detect failed\n"); 492 } else 493 dprintk("detected param = 0x%02X\n", detected_param); 494 495 /* Apply detected parameters */ 496 if (priv->config->prod == LGS8GXX_PROD_LGS8913) { 497 u8 inter_leave_len = detected_param & TIM_MASK ; 498 /* Fix 8913 time interleaver detection bug */ 499 inter_leave_len = (inter_leave_len == TIM_MIDDLE) ? 0x60 : 0x40; 500 detected_param &= CF_MASK | SC_MASK | LGS_FEC_MASK; 501 detected_param |= inter_leave_len; 502 } 503 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 504 u8 t; 505 lgs8gxx_read_reg(priv, 0x19, &t); 506 t &= 0x81; 507 t |= detected_param << 1; 508 lgs8gxx_write_reg(priv, 0x19, t); 509 } else { 510 lgs8gxx_write_reg(priv, 0x7D, detected_param); 511 if (priv->config->prod == LGS8GXX_PROD_LGS8913) 512 lgs8gxx_write_reg(priv, 0xC0, detected_param); 513 } 514 /* lgs8gxx_soft_reset(priv); */ 515 516 /* Enter manual mode */ 517 lgs8gxx_set_mode_manual(priv); 518 519 switch (gi) { 520 case GI_945: 521 priv->curr_gi = 945; break; 522 case GI_595: 523 priv->curr_gi = 595; break; 524 case GI_420: 525 priv->curr_gi = 420; break; 526 default: 527 priv->curr_gi = 945; break; 528 } 529 } 530 531 static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv, 532 u8 serial, u8 clk_pol, u8 clk_gated) 533 { 534 int ret = 0; 535 u8 t, reg_addr; 536 537 reg_addr = (priv->config->prod == LGS8GXX_PROD_LGS8G75) ? 0x30 : 0xC2; 538 ret = lgs8gxx_read_reg(priv, reg_addr, &t); 539 if (ret != 0) 540 return ret; 541 542 t &= 0xF8; 543 t |= serial ? TS_SERIAL : TS_PARALLEL; 544 t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL; 545 t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN; 546 547 ret = lgs8gxx_write_reg(priv, reg_addr, t); 548 if (ret != 0) 549 return ret; 550 551 return 0; 552 } 553 554 /* A/D input peak-to-peak voltage range */ 555 static int lgs8g75_set_adc_vpp(struct lgs8gxx_state *priv, 556 u8 sel) 557 { 558 u8 r26 = 0x73, r27 = 0x90; 559 560 if (priv->config->prod != LGS8GXX_PROD_LGS8G75) 561 return 0; 562 563 r26 |= (sel & 0x01) << 7; 564 r27 |= (sel & 0x02) >> 1; 565 lgs8gxx_write_reg(priv, 0x26, r26); 566 lgs8gxx_write_reg(priv, 0x27, r27); 567 568 return 0; 569 } 570 571 /* LGS8913 demod frontend functions */ 572 573 static int lgs8913_init(struct lgs8gxx_state *priv) 574 { 575 u8 t; 576 577 /* LGS8913 specific */ 578 lgs8gxx_write_reg(priv, 0xc1, 0x3); 579 580 lgs8gxx_read_reg(priv, 0x7c, &t); 581 lgs8gxx_write_reg(priv, 0x7c, (t&0x8c) | 0x3); 582 583 /* LGS8913 specific */ 584 lgs8gxx_read_reg(priv, 0xc3, &t); 585 lgs8gxx_write_reg(priv, 0xc3, t&0x10); 586 587 588 return 0; 589 } 590 591 static int lgs8g75_init_data(struct lgs8gxx_state *priv) 592 { 593 const struct firmware *fw; 594 int rc; 595 int i; 596 597 rc = request_firmware(&fw, LGS8GXX_FIRMWARE, &priv->i2c->dev); 598 if (rc) 599 return rc; 600 601 lgs8gxx_write_reg(priv, 0xC6, 0x40); 602 603 lgs8gxx_write_reg(priv, 0x3D, 0x04); 604 lgs8gxx_write_reg(priv, 0x39, 0x00); 605 606 lgs8gxx_write_reg(priv, 0x3A, 0x00); 607 lgs8gxx_write_reg(priv, 0x38, 0x00); 608 lgs8gxx_write_reg(priv, 0x3B, 0x00); 609 lgs8gxx_write_reg(priv, 0x38, 0x00); 610 611 for (i = 0; i < fw->size; i++) { 612 lgs8gxx_write_reg(priv, 0x38, 0x00); 613 lgs8gxx_write_reg(priv, 0x3A, (u8)(i&0xff)); 614 lgs8gxx_write_reg(priv, 0x3B, (u8)(i>>8)); 615 lgs8gxx_write_reg(priv, 0x3C, fw->data[i]); 616 } 617 618 lgs8gxx_write_reg(priv, 0x38, 0x00); 619 620 release_firmware(fw); 621 return 0; 622 } 623 624 static int lgs8gxx_init(struct dvb_frontend *fe) 625 { 626 struct lgs8gxx_state *priv = 627 (struct lgs8gxx_state *)fe->demodulator_priv; 628 const struct lgs8gxx_config *config = priv->config; 629 u8 data = 0; 630 s8 err; 631 dprintk("%s\n", __func__); 632 633 lgs8gxx_read_reg(priv, 0, &data); 634 dprintk("reg 0 = 0x%02X\n", data); 635 636 if (config->prod == LGS8GXX_PROD_LGS8G75) 637 lgs8g75_set_adc_vpp(priv, config->adc_vpp); 638 639 /* Setup MPEG output format */ 640 err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts, 641 config->ts_clk_pol, 642 config->ts_clk_gated); 643 if (err != 0) 644 return -EIO; 645 646 if (config->prod == LGS8GXX_PROD_LGS8913) 647 lgs8913_init(priv); 648 lgs8gxx_set_if_freq(priv, priv->config->if_freq); 649 lgs8gxx_set_ad_mode(priv); 650 651 return 0; 652 } 653 654 static void lgs8gxx_release(struct dvb_frontend *fe) 655 { 656 struct lgs8gxx_state *state = fe->demodulator_priv; 657 dprintk("%s\n", __func__); 658 659 kfree(state); 660 } 661 662 663 static int lgs8gxx_write(struct dvb_frontend *fe, const u8 buf[], int len) 664 { 665 struct lgs8gxx_state *priv = fe->demodulator_priv; 666 667 if (len != 2) 668 return -EINVAL; 669 670 return lgs8gxx_write_reg(priv, buf[0], buf[1]); 671 } 672 673 static int lgs8gxx_set_fe(struct dvb_frontend *fe) 674 { 675 struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache; 676 struct lgs8gxx_state *priv = fe->demodulator_priv; 677 678 dprintk("%s\n", __func__); 679 680 /* set frequency */ 681 if (fe->ops.tuner_ops.set_params) { 682 fe->ops.tuner_ops.set_params(fe); 683 if (fe->ops.i2c_gate_ctrl) 684 fe->ops.i2c_gate_ctrl(fe, 0); 685 } 686 687 /* start auto lock */ 688 lgs8gxx_auto_lock(priv); 689 690 msleep(10); 691 692 /* TODO: get real readings from device */ 693 694 /* bandwidth */ 695 fe_params->bandwidth_hz = 8000000; 696 697 fe_params->code_rate_HP = FEC_AUTO; 698 fe_params->code_rate_LP = FEC_AUTO; 699 700 fe_params->modulation = QAM_AUTO; 701 702 /* transmission mode */ 703 fe_params->transmission_mode = TRANSMISSION_MODE_AUTO; 704 705 /* guard interval */ 706 fe_params->guard_interval = GUARD_INTERVAL_AUTO; 707 708 /* hierarchy */ 709 fe_params->hierarchy = HIERARCHY_NONE; 710 711 return 0; 712 } 713 714 static 715 int lgs8gxx_get_tune_settings(struct dvb_frontend *fe, 716 struct dvb_frontend_tune_settings *fesettings) 717 { 718 /* FIXME: copy from tda1004x.c */ 719 fesettings->min_delay_ms = 800; 720 fesettings->step_size = 0; 721 fesettings->max_drift = 0; 722 return 0; 723 } 724 725 static int lgs8gxx_read_status(struct dvb_frontend *fe, 726 enum fe_status *fe_status) 727 { 728 struct lgs8gxx_state *priv = fe->demodulator_priv; 729 s8 ret; 730 u8 t, locked = 0; 731 732 dprintk("%s\n", __func__); 733 *fe_status = 0; 734 735 lgs8gxx_get_afc_phase(priv); 736 lgs8gxx_is_locked(priv, &locked); 737 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 738 if (locked) 739 *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | 740 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 741 return 0; 742 } 743 744 ret = lgs8gxx_read_reg(priv, 0x4B, &t); 745 if (ret != 0) 746 return -EIO; 747 748 dprintk("Reg 0x4B: 0x%02X\n", t); 749 750 *fe_status = 0; 751 if (priv->config->prod == LGS8GXX_PROD_LGS8913) { 752 if ((t & 0x40) == 0x40) 753 *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; 754 if ((t & 0x80) == 0x80) 755 *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | 756 FE_HAS_LOCK; 757 } else { 758 if ((t & 0x80) == 0x80) 759 *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | 760 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 761 } 762 763 /* success */ 764 dprintk("%s: fe_status=0x%x\n", __func__, *fe_status); 765 return 0; 766 } 767 768 static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal) 769 { 770 u16 v; 771 u8 agc_lvl[2], cat; 772 773 dprintk("%s()\n", __func__); 774 lgs8gxx_read_reg(priv, 0x3F, &agc_lvl[0]); 775 lgs8gxx_read_reg(priv, 0x3E, &agc_lvl[1]); 776 777 v = agc_lvl[0]; 778 v <<= 8; 779 v |= agc_lvl[1]; 780 781 dprintk("agc_lvl: 0x%04X\n", v); 782 783 if (v < 0x100) 784 cat = 0; 785 else if (v < 0x190) 786 cat = 5; 787 else if (v < 0x2A8) 788 cat = 4; 789 else if (v < 0x381) 790 cat = 3; 791 else if (v < 0x400) 792 cat = 2; 793 else if (v == 0x400) 794 cat = 1; 795 else 796 cat = 0; 797 798 *signal = cat * 65535 / 5; 799 800 return 0; 801 } 802 803 static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal) 804 { 805 u8 t; s8 ret; 806 s16 max_strength = 0; 807 u8 str; 808 u16 i, gi = priv->curr_gi; 809 810 dprintk("%s\n", __func__); 811 812 ret = lgs8gxx_read_reg(priv, 0x4B, &t); 813 if (ret != 0) 814 return -EIO; 815 816 if (fake_signal_str) { 817 if ((t & 0xC0) == 0xC0) { 818 dprintk("Fake signal strength\n"); 819 *signal = 0x7FFF; 820 } else 821 *signal = 0; 822 return 0; 823 } 824 825 dprintk("gi = %d\n", gi); 826 for (i = 0; i < gi; i++) { 827 828 if ((i & 0xFF) == 0) 829 lgs8gxx_write_reg(priv, 0x84, 0x03 & (i >> 8)); 830 lgs8gxx_write_reg(priv, 0x83, i & 0xFF); 831 832 lgs8gxx_read_reg(priv, 0x94, &str); 833 if (max_strength < str) 834 max_strength = str; 835 } 836 837 *signal = max_strength; 838 dprintk("%s: signal=0x%02X\n", __func__, *signal); 839 840 lgs8gxx_read_reg(priv, 0x95, &t); 841 dprintk("%s: AVG Noise=0x%02X\n", __func__, t); 842 843 return 0; 844 } 845 846 static int lgs8g75_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal) 847 { 848 u8 t; 849 s16 v = 0; 850 851 dprintk("%s\n", __func__); 852 853 lgs8gxx_read_reg(priv, 0xB1, &t); 854 v |= t; 855 v <<= 8; 856 lgs8gxx_read_reg(priv, 0xB0, &t); 857 v |= t; 858 859 *signal = v; 860 dprintk("%s: signal=0x%02X\n", __func__, *signal); 861 862 return 0; 863 } 864 865 static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal) 866 { 867 struct lgs8gxx_state *priv = fe->demodulator_priv; 868 869 if (priv->config->prod == LGS8GXX_PROD_LGS8913) 870 return lgs8913_read_signal_strength(priv, signal); 871 else if (priv->config->prod == LGS8GXX_PROD_LGS8G75) 872 return lgs8g75_read_signal_strength(priv, signal); 873 else 874 return lgs8gxx_read_signal_agc(priv, signal); 875 } 876 877 static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr) 878 { 879 struct lgs8gxx_state *priv = fe->demodulator_priv; 880 u8 t; 881 *snr = 0; 882 883 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) 884 lgs8gxx_read_reg(priv, 0x34, &t); 885 else 886 lgs8gxx_read_reg(priv, 0x95, &t); 887 dprintk("AVG Noise=0x%02X\n", t); 888 *snr = 256 - t; 889 *snr <<= 8; 890 dprintk("snr=0x%x\n", *snr); 891 892 return 0; 893 } 894 895 static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 896 { 897 *ucblocks = 0; 898 dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks); 899 return 0; 900 } 901 902 static void packet_counter_start(struct lgs8gxx_state *priv) 903 { 904 u8 orig, t; 905 906 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 907 lgs8gxx_read_reg(priv, 0x30, &orig); 908 orig &= 0xE7; 909 t = orig | 0x10; 910 lgs8gxx_write_reg(priv, 0x30, t); 911 t = orig | 0x18; 912 lgs8gxx_write_reg(priv, 0x30, t); 913 t = orig | 0x10; 914 lgs8gxx_write_reg(priv, 0x30, t); 915 } else { 916 lgs8gxx_write_reg(priv, 0xC6, 0x01); 917 lgs8gxx_write_reg(priv, 0xC6, 0x41); 918 lgs8gxx_write_reg(priv, 0xC6, 0x01); 919 } 920 } 921 922 static void packet_counter_stop(struct lgs8gxx_state *priv) 923 { 924 u8 t; 925 926 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 927 lgs8gxx_read_reg(priv, 0x30, &t); 928 t &= 0xE7; 929 lgs8gxx_write_reg(priv, 0x30, t); 930 } else { 931 lgs8gxx_write_reg(priv, 0xC6, 0x81); 932 } 933 } 934 935 static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber) 936 { 937 struct lgs8gxx_state *priv = fe->demodulator_priv; 938 u8 reg_err, reg_total, t; 939 u32 total_cnt = 0, err_cnt = 0; 940 int i; 941 942 dprintk("%s\n", __func__); 943 944 packet_counter_start(priv); 945 msleep(200); 946 packet_counter_stop(priv); 947 948 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 949 reg_total = 0x28; reg_err = 0x2C; 950 } else { 951 reg_total = 0xD0; reg_err = 0xD4; 952 } 953 954 for (i = 0; i < 4; i++) { 955 total_cnt <<= 8; 956 lgs8gxx_read_reg(priv, reg_total+3-i, &t); 957 total_cnt |= t; 958 } 959 for (i = 0; i < 4; i++) { 960 err_cnt <<= 8; 961 lgs8gxx_read_reg(priv, reg_err+3-i, &t); 962 err_cnt |= t; 963 } 964 dprintk("error=%d total=%d\n", err_cnt, total_cnt); 965 966 if (total_cnt == 0) 967 *ber = 0; 968 else 969 *ber = err_cnt * 100 / total_cnt; 970 971 dprintk("%s: ber=0x%x\n", __func__, *ber); 972 return 0; 973 } 974 975 static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 976 { 977 struct lgs8gxx_state *priv = fe->demodulator_priv; 978 979 if (priv->config->tuner_address == 0) 980 return 0; 981 if (enable) { 982 u8 v = 0x80 | priv->config->tuner_address; 983 return lgs8gxx_write_reg(priv, 0x01, v); 984 } 985 return lgs8gxx_write_reg(priv, 0x01, 0); 986 } 987 988 static struct dvb_frontend_ops lgs8gxx_ops = { 989 .delsys = { SYS_DTMB }, 990 .info = { 991 .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH", 992 .frequency_min = 474000000, 993 .frequency_max = 858000000, 994 .frequency_stepsize = 10000, 995 .caps = 996 FE_CAN_FEC_AUTO | 997 FE_CAN_QAM_AUTO | 998 FE_CAN_TRANSMISSION_MODE_AUTO | 999 FE_CAN_GUARD_INTERVAL_AUTO 1000 }, 1001 1002 .release = lgs8gxx_release, 1003 1004 .init = lgs8gxx_init, 1005 .write = lgs8gxx_write, 1006 .i2c_gate_ctrl = lgs8gxx_i2c_gate_ctrl, 1007 1008 .set_frontend = lgs8gxx_set_fe, 1009 .get_tune_settings = lgs8gxx_get_tune_settings, 1010 1011 .read_status = lgs8gxx_read_status, 1012 .read_ber = lgs8gxx_read_ber, 1013 .read_signal_strength = lgs8gxx_read_signal_strength, 1014 .read_snr = lgs8gxx_read_snr, 1015 .read_ucblocks = lgs8gxx_read_ucblocks, 1016 }; 1017 1018 struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config, 1019 struct i2c_adapter *i2c) 1020 { 1021 struct lgs8gxx_state *priv = NULL; 1022 u8 data = 0; 1023 1024 dprintk("%s()\n", __func__); 1025 1026 if (config == NULL || i2c == NULL) 1027 return NULL; 1028 1029 priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL); 1030 if (priv == NULL) 1031 goto error_out; 1032 1033 priv->config = config; 1034 priv->i2c = i2c; 1035 1036 /* check if the demod is there */ 1037 if (lgs8gxx_read_reg(priv, 0, &data) != 0) { 1038 dprintk("%s lgs8gxx not found at i2c addr 0x%02X\n", 1039 __func__, priv->config->demod_address); 1040 goto error_out; 1041 } 1042 1043 lgs8gxx_read_reg(priv, 1, &data); 1044 1045 memcpy(&priv->frontend.ops, &lgs8gxx_ops, 1046 sizeof(struct dvb_frontend_ops)); 1047 priv->frontend.demodulator_priv = priv; 1048 1049 if (config->prod == LGS8GXX_PROD_LGS8G75) 1050 lgs8g75_init_data(priv); 1051 1052 return &priv->frontend; 1053 1054 error_out: 1055 dprintk("%s() error_out\n", __func__); 1056 kfree(priv); 1057 return NULL; 1058 1059 } 1060 EXPORT_SYMBOL(lgs8gxx_attach); 1061 1062 MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver"); 1063 MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>"); 1064 MODULE_LICENSE("GPL"); 1065 MODULE_FIRMWARE(LGS8GXX_FIRMWARE); 1066