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