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