Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.0-rc7 2397 lines 64 kB view raw
1/* 2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC). 3 * 4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation, version 2. 9 */ 10#include <linux/kernel.h> 11#include <linux/slab.h> 12#include <linux/i2c.h> 13 14#include "dvb_math.h" 15#include "dvb_frontend.h" 16 17#include "dib7000p.h" 18 19static int debug; 20module_param(debug, int, 0644); 21MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 22 23static int buggy_sfn_workaround; 24module_param(buggy_sfn_workaround, int, 0644); 25MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)"); 26 27#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0) 28 29struct i2c_device { 30 struct i2c_adapter *i2c_adap; 31 u8 i2c_addr; 32}; 33 34struct dib7000p_state { 35 struct dvb_frontend demod; 36 struct dib7000p_config cfg; 37 38 u8 i2c_addr; 39 struct i2c_adapter *i2c_adap; 40 41 struct dibx000_i2c_master i2c_master; 42 43 u16 wbd_ref; 44 45 u8 current_band; 46 u32 current_bandwidth; 47 struct dibx000_agc_config *current_agc; 48 u32 timf; 49 50 u8 div_force_off:1; 51 u8 div_state:1; 52 u16 div_sync_wait; 53 54 u8 agc_state; 55 56 u16 gpio_dir; 57 u16 gpio_val; 58 59 u8 sfn_workaround_active:1; 60 61#define SOC7090 0x7090 62 u16 version; 63 64 u16 tuner_enable; 65 struct i2c_adapter dib7090_tuner_adap; 66 67 /* for the I2C transfer */ 68 struct i2c_msg msg[2]; 69 u8 i2c_write_buffer[4]; 70 u8 i2c_read_buffer[2]; 71}; 72 73enum dib7000p_power_mode { 74 DIB7000P_POWER_ALL = 0, 75 DIB7000P_POWER_ANALOG_ADC, 76 DIB7000P_POWER_INTERFACE_ONLY, 77}; 78 79static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode); 80static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); 81 82static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) 83{ 84 state->i2c_write_buffer[0] = reg >> 8; 85 state->i2c_write_buffer[1] = reg & 0xff; 86 87 memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); 88 state->msg[0].addr = state->i2c_addr >> 1; 89 state->msg[0].flags = 0; 90 state->msg[0].buf = state->i2c_write_buffer; 91 state->msg[0].len = 2; 92 state->msg[1].addr = state->i2c_addr >> 1; 93 state->msg[1].flags = I2C_M_RD; 94 state->msg[1].buf = state->i2c_read_buffer; 95 state->msg[1].len = 2; 96 97 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2) 98 dprintk("i2c read error on %d", reg); 99 100 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; 101} 102 103static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) 104{ 105 state->i2c_write_buffer[0] = (reg >> 8) & 0xff; 106 state->i2c_write_buffer[1] = reg & 0xff; 107 state->i2c_write_buffer[2] = (val >> 8) & 0xff; 108 state->i2c_write_buffer[3] = val & 0xff; 109 110 memset(&state->msg[0], 0, sizeof(struct i2c_msg)); 111 state->msg[0].addr = state->i2c_addr >> 1; 112 state->msg[0].flags = 0; 113 state->msg[0].buf = state->i2c_write_buffer; 114 state->msg[0].len = 4; 115 116 return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0; 117} 118 119static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf) 120{ 121 u16 l = 0, r, *n; 122 n = buf; 123 l = *n++; 124 while (l) { 125 r = *n++; 126 127 do { 128 dib7000p_write_word(state, r, *n++); 129 r++; 130 } while (--l); 131 l = *n++; 132 } 133} 134 135static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) 136{ 137 int ret = 0; 138 u16 outreg, fifo_threshold, smo_mode; 139 140 outreg = 0; 141 fifo_threshold = 1792; 142 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1); 143 144 dprintk("setting output mode for demod %p to %d", &state->demod, mode); 145 146 switch (mode) { 147 case OUTMODE_MPEG2_PAR_GATED_CLK: 148 outreg = (1 << 10); /* 0x0400 */ 149 break; 150 case OUTMODE_MPEG2_PAR_CONT_CLK: 151 outreg = (1 << 10) | (1 << 6); /* 0x0440 */ 152 break; 153 case OUTMODE_MPEG2_SERIAL: 154 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */ 155 break; 156 case OUTMODE_DIVERSITY: 157 if (state->cfg.hostbus_diversity) 158 outreg = (1 << 10) | (4 << 6); /* 0x0500 */ 159 else 160 outreg = (1 << 11); 161 break; 162 case OUTMODE_MPEG2_FIFO: 163 smo_mode |= (3 << 1); 164 fifo_threshold = 512; 165 outreg = (1 << 10) | (5 << 6); 166 break; 167 case OUTMODE_ANALOG_ADC: 168 outreg = (1 << 10) | (3 << 6); 169 break; 170 case OUTMODE_HIGH_Z: 171 outreg = 0; 172 break; 173 default: 174 dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod); 175 break; 176 } 177 178 if (state->cfg.output_mpeg2_in_188_bytes) 179 smo_mode |= (1 << 5); 180 181 ret |= dib7000p_write_word(state, 235, smo_mode); 182 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ 183 if (state->version != SOC7090) 184 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */ 185 186 return ret; 187} 188 189static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff) 190{ 191 struct dib7000p_state *state = demod->demodulator_priv; 192 193 if (state->div_force_off) { 194 dprintk("diversity combination deactivated - forced by COFDM parameters"); 195 onoff = 0; 196 dib7000p_write_word(state, 207, 0); 197 } else 198 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0)); 199 200 state->div_state = (u8) onoff; 201 202 if (onoff) { 203 dib7000p_write_word(state, 204, 6); 204 dib7000p_write_word(state, 205, 16); 205 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */ 206 } else { 207 dib7000p_write_word(state, 204, 1); 208 dib7000p_write_word(state, 205, 0); 209 } 210 211 return 0; 212} 213 214static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode) 215{ 216 /* by default everything is powered off */ 217 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff); 218 219 /* now, depending on the requested mode, we power on */ 220 switch (mode) { 221 /* power up everything in the demod */ 222 case DIB7000P_POWER_ALL: 223 reg_774 = 0x0000; 224 reg_775 = 0x0000; 225 reg_776 = 0x0; 226 reg_899 = 0x0; 227 if (state->version == SOC7090) 228 reg_1280 &= 0x001f; 229 else 230 reg_1280 &= 0x01ff; 231 break; 232 233 case DIB7000P_POWER_ANALOG_ADC: 234 /* dem, cfg, iqc, sad, agc */ 235 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9)); 236 /* nud */ 237 reg_776 &= ~((1 << 0)); 238 /* Dout */ 239 if (state->version != SOC7090) 240 reg_1280 &= ~((1 << 11)); 241 reg_1280 &= ~(1 << 6); 242 /* fall through wanted to enable the interfaces */ 243 244 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */ 245 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */ 246 if (state->version == SOC7090) 247 reg_1280 &= ~((1 << 7) | (1 << 5)); 248 else 249 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10)); 250 break; 251 252/* TODO following stuff is just converted from the dib7000-driver - check when is used what */ 253 } 254 255 dib7000p_write_word(state, 774, reg_774); 256 dib7000p_write_word(state, 775, reg_775); 257 dib7000p_write_word(state, 776, reg_776); 258 dib7000p_write_word(state, 899, reg_899); 259 dib7000p_write_word(state, 1280, reg_1280); 260 261 return 0; 262} 263 264static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no) 265{ 266 u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909); 267 u16 reg; 268 269 switch (no) { 270 case DIBX000_SLOW_ADC_ON: 271 if (state->version == SOC7090) { 272 reg = dib7000p_read_word(state, 1925); 273 274 dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */ 275 276 reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */ 277 msleep(200); 278 dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */ 279 280 reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12)); 281 dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */ 282 } else { 283 reg_909 |= (1 << 1) | (1 << 0); 284 dib7000p_write_word(state, 909, reg_909); 285 reg_909 &= ~(1 << 1); 286 } 287 break; 288 289 case DIBX000_SLOW_ADC_OFF: 290 if (state->version == SOC7090) { 291 reg = dib7000p_read_word(state, 1925); 292 dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */ 293 } else 294 reg_909 |= (1 << 1) | (1 << 0); 295 break; 296 297 case DIBX000_ADC_ON: 298 reg_908 &= 0x0fff; 299 reg_909 &= 0x0003; 300 break; 301 302 case DIBX000_ADC_OFF: 303 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12); 304 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2); 305 break; 306 307 case DIBX000_VBG_ENABLE: 308 reg_908 &= ~(1 << 15); 309 break; 310 311 case DIBX000_VBG_DISABLE: 312 reg_908 |= (1 << 15); 313 break; 314 315 default: 316 break; 317 } 318 319// dprintk( "908: %x, 909: %x\n", reg_908, reg_909); 320 321 reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4; 322 reg_908 |= (state->cfg.enable_current_mirror & 1) << 7; 323 324 dib7000p_write_word(state, 908, reg_908); 325 dib7000p_write_word(state, 909, reg_909); 326} 327 328static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw) 329{ 330 u32 timf; 331 332 // store the current bandwidth for later use 333 state->current_bandwidth = bw; 334 335 if (state->timf == 0) { 336 dprintk("using default timf"); 337 timf = state->cfg.bw->timf; 338 } else { 339 dprintk("using updated timf"); 340 timf = state->timf; 341 } 342 343 timf = timf * (bw / 50) / 160; 344 345 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff)); 346 dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff)); 347 348 return 0; 349} 350 351static int dib7000p_sad_calib(struct dib7000p_state *state) 352{ 353/* internal */ 354 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0)); 355 356 if (state->version == SOC7090) 357 dib7000p_write_word(state, 74, 2048); 358 else 359 dib7000p_write_word(state, 74, 776); 360 361 /* do the calibration */ 362 dib7000p_write_word(state, 73, (1 << 0)); 363 dib7000p_write_word(state, 73, (0 << 0)); 364 365 msleep(1); 366 367 return 0; 368} 369 370int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value) 371{ 372 struct dib7000p_state *state = demod->demodulator_priv; 373 if (value > 4095) 374 value = 4095; 375 state->wbd_ref = value; 376 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value); 377} 378EXPORT_SYMBOL(dib7000p_set_wbd_ref); 379 380static void dib7000p_reset_pll(struct dib7000p_state *state) 381{ 382 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; 383 u16 clk_cfg0; 384 385 if (state->version == SOC7090) { 386 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv)); 387 388 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1) 389 ; 390 391 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15)); 392 } else { 393 /* force PLL bypass */ 394 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) | 395 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0); 396 397 dib7000p_write_word(state, 900, clk_cfg0); 398 399 /* P_pll_cfg */ 400 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset); 401 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff); 402 dib7000p_write_word(state, 900, clk_cfg0); 403 } 404 405 dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); 406 dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff)); 407 dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff)); 408 dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff)); 409 410 dib7000p_write_word(state, 72, bw->sad_cfg); 411} 412 413static u32 dib7000p_get_internal_freq(struct dib7000p_state *state) 414{ 415 u32 internal = (u32) dib7000p_read_word(state, 18) << 16; 416 internal |= (u32) dib7000p_read_word(state, 19); 417 internal /= 1000; 418 419 return internal; 420} 421 422int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw) 423{ 424 struct dib7000p_state *state = fe->demodulator_priv; 425 u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856); 426 u8 loopdiv, prediv; 427 u32 internal, xtal; 428 429 /* get back old values */ 430 prediv = reg_1856 & 0x3f; 431 loopdiv = (reg_1856 >> 6) & 0x3f; 432 433 if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) { 434 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio); 435 reg_1856 &= 0xf000; 436 reg_1857 = dib7000p_read_word(state, 1857); 437 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15)); 438 439 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f)); 440 441 /* write new system clk into P_sec_len */ 442 internal = dib7000p_get_internal_freq(state); 443 xtal = (internal / loopdiv) * prediv; 444 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */ 445 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff)); 446 dib7000p_write_word(state, 19, (u16) (internal & 0xffff)); 447 448 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15)); 449 450 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1) 451 dprintk("Waiting for PLL to lock"); 452 453 return 0; 454 } 455 return -EIO; 456} 457EXPORT_SYMBOL(dib7000p_update_pll); 458 459static int dib7000p_reset_gpio(struct dib7000p_state *st) 460{ 461 /* reset the GPIOs */ 462 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos); 463 464 dib7000p_write_word(st, 1029, st->gpio_dir); 465 dib7000p_write_word(st, 1030, st->gpio_val); 466 467 /* TODO 1031 is P_gpio_od */ 468 469 dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos); 470 471 dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div); 472 return 0; 473} 474 475static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val) 476{ 477 st->gpio_dir = dib7000p_read_word(st, 1029); 478 st->gpio_dir &= ~(1 << num); /* reset the direction bit */ 479 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */ 480 dib7000p_write_word(st, 1029, st->gpio_dir); 481 482 st->gpio_val = dib7000p_read_word(st, 1030); 483 st->gpio_val &= ~(1 << num); /* reset the direction bit */ 484 st->gpio_val |= (val & 0x01) << num; /* set the new value */ 485 dib7000p_write_word(st, 1030, st->gpio_val); 486 487 return 0; 488} 489 490int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val) 491{ 492 struct dib7000p_state *state = demod->demodulator_priv; 493 return dib7000p_cfg_gpio(state, num, dir, val); 494} 495EXPORT_SYMBOL(dib7000p_set_gpio); 496 497static u16 dib7000p_defaults[] = { 498 // auto search configuration 499 3, 2, 500 0x0004, 501 0x1000, 502 0x0814, /* Equal Lock */ 503 504 12, 6, 505 0x001b, 506 0x7740, 507 0x005b, 508 0x8d80, 509 0x01c9, 510 0xc380, 511 0x0000, 512 0x0080, 513 0x0000, 514 0x0090, 515 0x0001, 516 0xd4c0, 517 518 1, 26, 519 0x6680, 520 521 /* set ADC level to -16 */ 522 11, 79, 523 (1 << 13) - 825 - 117, 524 (1 << 13) - 837 - 117, 525 (1 << 13) - 811 - 117, 526 (1 << 13) - 766 - 117, 527 (1 << 13) - 737 - 117, 528 (1 << 13) - 693 - 117, 529 (1 << 13) - 648 - 117, 530 (1 << 13) - 619 - 117, 531 (1 << 13) - 575 - 117, 532 (1 << 13) - 531 - 117, 533 (1 << 13) - 501 - 117, 534 535 1, 142, 536 0x0410, 537 538 /* disable power smoothing */ 539 8, 145, 540 0, 541 0, 542 0, 543 0, 544 0, 545 0, 546 0, 547 0, 548 549 1, 154, 550 1 << 13, 551 552 1, 168, 553 0x0ccd, 554 555 1, 183, 556 0x200f, 557 558 1, 212, 559 0x169, 560 561 5, 187, 562 0x023d, 563 0x00a4, 564 0x00a4, 565 0x7ff0, 566 0x3ccc, 567 568 1, 198, 569 0x800, 570 571 1, 222, 572 0x0010, 573 574 1, 235, 575 0x0062, 576 577 2, 901, 578 0x0006, 579 (3 << 10) | (1 << 6), 580 581 1, 905, 582 0x2c8e, 583 584 0, 585}; 586 587static int dib7000p_demod_reset(struct dib7000p_state *state) 588{ 589 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 590 591 if (state->version == SOC7090) 592 dibx000_reset_i2c_master(&state->i2c_master); 593 594 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE); 595 596 /* restart all parts */ 597 dib7000p_write_word(state, 770, 0xffff); 598 dib7000p_write_word(state, 771, 0xffff); 599 dib7000p_write_word(state, 772, 0x001f); 600 dib7000p_write_word(state, 898, 0x0003); 601 dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3))); 602 603 dib7000p_write_word(state, 770, 0); 604 dib7000p_write_word(state, 771, 0); 605 dib7000p_write_word(state, 772, 0); 606 dib7000p_write_word(state, 898, 0); 607 dib7000p_write_word(state, 1280, 0); 608 609 /* default */ 610 dib7000p_reset_pll(state); 611 612 if (dib7000p_reset_gpio(state) != 0) 613 dprintk("GPIO reset was not successful."); 614 615 if (state->version == SOC7090) { 616 dib7000p_write_word(state, 899, 0); 617 618 /* impulse noise */ 619 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */ 620 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */ 621 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */ 622 dib7000p_write_word(state, 273, (1<<6) | 30); 623 } 624 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) 625 dprintk("OUTPUT_MODE could not be reset."); 626 627 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); 628 dib7000p_sad_calib(state); 629 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF); 630 631 /* unforce divstr regardless whether i2c enumeration was done or not */ 632 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1)); 633 634 dib7000p_set_bandwidth(state, 8000); 635 636 if (state->version == SOC7090) { 637 dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */ 638 } else { 639 if (state->cfg.tuner_is_baseband) 640 dib7000p_write_word(state, 36, 0x0755); 641 else 642 dib7000p_write_word(state, 36, 0x1f55); 643 } 644 645 dib7000p_write_tab(state, dib7000p_defaults); 646 647 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); 648 649 return 0; 650} 651 652static void dib7000p_pll_clk_cfg(struct dib7000p_state *state) 653{ 654 u16 tmp = 0; 655 tmp = dib7000p_read_word(state, 903); 656 dib7000p_write_word(state, 903, (tmp | 0x1)); 657 tmp = dib7000p_read_word(state, 900); 658 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); 659} 660 661static void dib7000p_restart_agc(struct dib7000p_state *state) 662{ 663 // P_restart_iqc & P_restart_agc 664 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9)); 665 dib7000p_write_word(state, 770, 0x0000); 666} 667 668static int dib7000p_update_lna(struct dib7000p_state *state) 669{ 670 u16 dyn_gain; 671 672 if (state->cfg.update_lna) { 673 dyn_gain = dib7000p_read_word(state, 394); 674 if (state->cfg.update_lna(&state->demod, dyn_gain)) { 675 dib7000p_restart_agc(state); 676 return 1; 677 } 678 } 679 680 return 0; 681} 682 683static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band) 684{ 685 struct dibx000_agc_config *agc = NULL; 686 int i; 687 if (state->current_band == band && state->current_agc != NULL) 688 return 0; 689 state->current_band = band; 690 691 for (i = 0; i < state->cfg.agc_config_count; i++) 692 if (state->cfg.agc[i].band_caps & band) { 693 agc = &state->cfg.agc[i]; 694 break; 695 } 696 697 if (agc == NULL) { 698 dprintk("no valid AGC configuration found for band 0x%02x", band); 699 return -EINVAL; 700 } 701 702 state->current_agc = agc; 703 704 /* AGC */ 705 dib7000p_write_word(state, 75, agc->setup); 706 dib7000p_write_word(state, 76, agc->inv_gain); 707 dib7000p_write_word(state, 77, agc->time_stabiliz); 708 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock); 709 710 // Demod AGC loop configuration 711 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp); 712 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp); 713 714 /* AGC continued */ 715 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d", 716 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); 717 718 if (state->wbd_ref != 0) 719 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref); 720 else 721 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref); 722 723 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); 724 725 dib7000p_write_word(state, 107, agc->agc1_max); 726 dib7000p_write_word(state, 108, agc->agc1_min); 727 dib7000p_write_word(state, 109, agc->agc2_max); 728 dib7000p_write_word(state, 110, agc->agc2_min); 729 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2); 730 dib7000p_write_word(state, 112, agc->agc1_pt3); 731 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2); 732 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2); 733 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); 734 return 0; 735} 736 737static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz) 738{ 739 u32 internal = dib7000p_get_internal_freq(state); 740 s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */ 741 u32 abs_offset_khz = ABS(offset_khz); 742 u32 dds = state->cfg.bw->ifreq & 0x1ffffff; 743 u8 invert = !!(state->cfg.bw->ifreq & (1 << 25)); 744 745 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert); 746 747 if (offset_khz < 0) 748 unit_khz_dds_val *= -1; 749 750 /* IF tuner */ 751 if (invert) 752 dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */ 753 else 754 dds += (abs_offset_khz * unit_khz_dds_val); 755 756 if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */ 757 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9))); 758 dib7000p_write_word(state, 22, (u16) (dds & 0xffff)); 759 } 760} 761 762static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) 763{ 764 struct dib7000p_state *state = demod->demodulator_priv; 765 int ret = -1; 766 u8 *agc_state = &state->agc_state; 767 u8 agc_split; 768 u16 reg; 769 u32 upd_demod_gain_period = 0x1000; 770 771 switch (state->agc_state) { 772 case 0: 773 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 774 if (state->version == SOC7090) { 775 reg = dib7000p_read_word(state, 0x79b) & 0xff00; 776 dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */ 777 dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF)); 778 779 /* enable adc i & q */ 780 reg = dib7000p_read_word(state, 0x780); 781 dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7))); 782 } else { 783 dib7000p_set_adc_state(state, DIBX000_ADC_ON); 784 dib7000p_pll_clk_cfg(state); 785 } 786 787 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0) 788 return -1; 789 790 dib7000p_set_dds(state, 0); 791 ret = 7; 792 (*agc_state)++; 793 break; 794 795 case 1: 796 if (state->cfg.agc_control) 797 state->cfg.agc_control(&state->demod, 1); 798 799 dib7000p_write_word(state, 78, 32768); 800 if (!state->current_agc->perform_agc_softsplit) { 801 /* we are using the wbd - so slow AGC startup */ 802 /* force 0 split on WBD and restart AGC */ 803 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8)); 804 (*agc_state)++; 805 ret = 5; 806 } else { 807 /* default AGC startup */ 808 (*agc_state) = 4; 809 /* wait AGC rough lock time */ 810 ret = 7; 811 } 812 813 dib7000p_restart_agc(state); 814 break; 815 816 case 2: /* fast split search path after 5sec */ 817 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */ 818 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */ 819 (*agc_state)++; 820 ret = 14; 821 break; 822 823 case 3: /* split search ended */ 824 agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */ 825 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */ 826 827 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */ 828 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */ 829 830 dib7000p_restart_agc(state); 831 832 dprintk("SPLIT %p: %hd", demod, agc_split); 833 834 (*agc_state)++; 835 ret = 5; 836 break; 837 838 case 4: /* LNA startup */ 839 ret = 7; 840 841 if (dib7000p_update_lna(state)) 842 ret = 5; 843 else 844 (*agc_state)++; 845 break; 846 847 case 5: 848 if (state->cfg.agc_control) 849 state->cfg.agc_control(&state->demod, 0); 850 (*agc_state)++; 851 break; 852 default: 853 break; 854 } 855 return ret; 856} 857 858static void dib7000p_update_timf(struct dib7000p_state *state) 859{ 860 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428); 861 state->timf = timf * 160 / (state->current_bandwidth / 50); 862 dib7000p_write_word(state, 23, (u16) (timf >> 16)); 863 dib7000p_write_word(state, 24, (u16) (timf & 0xffff)); 864 dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf); 865 866} 867 868u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf) 869{ 870 struct dib7000p_state *state = fe->demodulator_priv; 871 switch (op) { 872 case DEMOD_TIMF_SET: 873 state->timf = timf; 874 break; 875 case DEMOD_TIMF_UPDATE: 876 dib7000p_update_timf(state); 877 break; 878 case DEMOD_TIMF_GET: 879 break; 880 } 881 dib7000p_set_bandwidth(state, state->current_bandwidth); 882 return state->timf; 883} 884EXPORT_SYMBOL(dib7000p_ctrl_timf); 885 886static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq) 887{ 888 u16 value, est[4]; 889 890 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); 891 892 /* nfft, guard, qam, alpha */ 893 value = 0; 894 switch (ch->u.ofdm.transmission_mode) { 895 case TRANSMISSION_MODE_2K: 896 value |= (0 << 7); 897 break; 898 case TRANSMISSION_MODE_4K: 899 value |= (2 << 7); 900 break; 901 default: 902 case TRANSMISSION_MODE_8K: 903 value |= (1 << 7); 904 break; 905 } 906 switch (ch->u.ofdm.guard_interval) { 907 case GUARD_INTERVAL_1_32: 908 value |= (0 << 5); 909 break; 910 case GUARD_INTERVAL_1_16: 911 value |= (1 << 5); 912 break; 913 case GUARD_INTERVAL_1_4: 914 value |= (3 << 5); 915 break; 916 default: 917 case GUARD_INTERVAL_1_8: 918 value |= (2 << 5); 919 break; 920 } 921 switch (ch->u.ofdm.constellation) { 922 case QPSK: 923 value |= (0 << 3); 924 break; 925 case QAM_16: 926 value |= (1 << 3); 927 break; 928 default: 929 case QAM_64: 930 value |= (2 << 3); 931 break; 932 } 933 switch (HIERARCHY_1) { 934 case HIERARCHY_2: 935 value |= 2; 936 break; 937 case HIERARCHY_4: 938 value |= 4; 939 break; 940 default: 941 case HIERARCHY_1: 942 value |= 1; 943 break; 944 } 945 dib7000p_write_word(state, 0, value); 946 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */ 947 948 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */ 949 value = 0; 950 if (1 != 0) 951 value |= (1 << 6); 952 if (ch->u.ofdm.hierarchy_information == 1) 953 value |= (1 << 4); 954 if (1 == 1) 955 value |= 1; 956 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { 957 case FEC_2_3: 958 value |= (2 << 1); 959 break; 960 case FEC_3_4: 961 value |= (3 << 1); 962 break; 963 case FEC_5_6: 964 value |= (5 << 1); 965 break; 966 case FEC_7_8: 967 value |= (7 << 1); 968 break; 969 default: 970 case FEC_1_2: 971 value |= (1 << 1); 972 break; 973 } 974 dib7000p_write_word(state, 208, value); 975 976 /* offset loop parameters */ 977 dib7000p_write_word(state, 26, 0x6680); 978 dib7000p_write_word(state, 32, 0x0003); 979 dib7000p_write_word(state, 29, 0x1273); 980 dib7000p_write_word(state, 33, 0x0005); 981 982 /* P_dvsy_sync_wait */ 983 switch (ch->u.ofdm.transmission_mode) { 984 case TRANSMISSION_MODE_8K: 985 value = 256; 986 break; 987 case TRANSMISSION_MODE_4K: 988 value = 128; 989 break; 990 case TRANSMISSION_MODE_2K: 991 default: 992 value = 64; 993 break; 994 } 995 switch (ch->u.ofdm.guard_interval) { 996 case GUARD_INTERVAL_1_16: 997 value *= 2; 998 break; 999 case GUARD_INTERVAL_1_8: 1000 value *= 4; 1001 break; 1002 case GUARD_INTERVAL_1_4: 1003 value *= 8; 1004 break; 1005 default: 1006 case GUARD_INTERVAL_1_32: 1007 value *= 1; 1008 break; 1009 } 1010 if (state->cfg.diversity_delay == 0) 1011 state->div_sync_wait = (value * 3) / 2 + 48; 1012 else 1013 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; 1014 1015 /* deactive the possibility of diversity reception if extended interleaver */ 1016 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; 1017 dib7000p_set_diversity_in(&state->demod, state->div_state); 1018 1019 /* channel estimation fine configuration */ 1020 switch (ch->u.ofdm.constellation) { 1021 case QAM_64: 1022 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ 1023 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ 1024 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 1025 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */ 1026 break; 1027 case QAM_16: 1028 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */ 1029 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */ 1030 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 1031 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */ 1032 break; 1033 default: 1034 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */ 1035 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */ 1036 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */ 1037 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */ 1038 break; 1039 } 1040 for (value = 0; value < 4; value++) 1041 dib7000p_write_word(state, 187 + value, est[value]); 1042} 1043 1044static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) 1045{ 1046 struct dib7000p_state *state = demod->demodulator_priv; 1047 struct dvb_frontend_parameters schan; 1048 u32 value, factor; 1049 u32 internal = dib7000p_get_internal_freq(state); 1050 1051 schan = *ch; 1052 schan.u.ofdm.constellation = QAM_64; 1053 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; 1054 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; 1055 schan.u.ofdm.code_rate_HP = FEC_2_3; 1056 schan.u.ofdm.code_rate_LP = FEC_3_4; 1057 schan.u.ofdm.hierarchy_information = 0; 1058 1059 dib7000p_set_channel(state, &schan, 7); 1060 1061 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); 1062 if (factor >= 5000) 1063 factor = 1; 1064 else 1065 factor = 6; 1066 1067 value = 30 * internal * factor; 1068 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); 1069 dib7000p_write_word(state, 7, (u16) (value & 0xffff)); 1070 value = 100 * internal * factor; 1071 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); 1072 dib7000p_write_word(state, 9, (u16) (value & 0xffff)); 1073 value = 500 * internal * factor; 1074 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); 1075 dib7000p_write_word(state, 11, (u16) (value & 0xffff)); 1076 1077 value = dib7000p_read_word(state, 0); 1078 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value)); 1079 dib7000p_read_word(state, 1284); 1080 dib7000p_write_word(state, 0, (u16) value); 1081 1082 return 0; 1083} 1084 1085static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod) 1086{ 1087 struct dib7000p_state *state = demod->demodulator_priv; 1088 u16 irq_pending = dib7000p_read_word(state, 1284); 1089 1090 if (irq_pending & 0x1) 1091 return 1; 1092 1093 if (irq_pending & 0x2) 1094 return 2; 1095 1096 return 0; 1097} 1098 1099static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw) 1100{ 1101 static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 }; 1102 static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22, 1103 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, 1104 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80, 1105 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105, 1106 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126, 1107 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146, 1108 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165, 1109 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, 1110 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 1111 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212, 1112 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224, 1113 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235, 1114 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243, 1115 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249, 1116 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254, 1117 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1118 255, 255, 255, 255, 255, 255 1119 }; 1120 1121 u32 xtal = state->cfg.bw->xtal_hz / 1000; 1122 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz; 1123 int k; 1124 int coef_re[8], coef_im[8]; 1125 int bw_khz = bw; 1126 u32 pha; 1127 1128 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal); 1129 1130 if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2) 1131 return; 1132 1133 bw_khz /= 100; 1134 1135 dib7000p_write_word(state, 142, 0x0610); 1136 1137 for (k = 0; k < 8; k++) { 1138 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff; 1139 1140 if (pha == 0) { 1141 coef_re[k] = 256; 1142 coef_im[k] = 0; 1143 } else if (pha < 256) { 1144 coef_re[k] = sine[256 - (pha & 0xff)]; 1145 coef_im[k] = sine[pha & 0xff]; 1146 } else if (pha == 256) { 1147 coef_re[k] = 0; 1148 coef_im[k] = 256; 1149 } else if (pha < 512) { 1150 coef_re[k] = -sine[pha & 0xff]; 1151 coef_im[k] = sine[256 - (pha & 0xff)]; 1152 } else if (pha == 512) { 1153 coef_re[k] = -256; 1154 coef_im[k] = 0; 1155 } else if (pha < 768) { 1156 coef_re[k] = -sine[256 - (pha & 0xff)]; 1157 coef_im[k] = -sine[pha & 0xff]; 1158 } else if (pha == 768) { 1159 coef_re[k] = 0; 1160 coef_im[k] = -256; 1161 } else { 1162 coef_re[k] = sine[pha & 0xff]; 1163 coef_im[k] = -sine[256 - (pha & 0xff)]; 1164 } 1165 1166 coef_re[k] *= notch[k]; 1167 coef_re[k] += (1 << 14); 1168 if (coef_re[k] >= (1 << 24)) 1169 coef_re[k] = (1 << 24) - 1; 1170 coef_re[k] /= (1 << 15); 1171 1172 coef_im[k] *= notch[k]; 1173 coef_im[k] += (1 << 14); 1174 if (coef_im[k] >= (1 << 24)) 1175 coef_im[k] = (1 << 24) - 1; 1176 coef_im[k] /= (1 << 15); 1177 1178 dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]); 1179 1180 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); 1181 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff); 1182 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); 1183 } 1184 dib7000p_write_word(state, 143, 0); 1185} 1186 1187static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) 1188{ 1189 struct dib7000p_state *state = demod->demodulator_priv; 1190 u16 tmp = 0; 1191 1192 if (ch != NULL) 1193 dib7000p_set_channel(state, ch, 0); 1194 else 1195 return -EINVAL; 1196 1197 // restart demod 1198 dib7000p_write_word(state, 770, 0x4000); 1199 dib7000p_write_word(state, 770, 0x0000); 1200 msleep(45); 1201 1202 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ 1203 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3); 1204 if (state->sfn_workaround_active) { 1205 dprintk("SFN workaround is active"); 1206 tmp |= (1 << 9); 1207 dib7000p_write_word(state, 166, 0x4000); 1208 } else { 1209 dib7000p_write_word(state, 166, 0x0000); 1210 } 1211 dib7000p_write_word(state, 29, tmp); 1212 1213 // never achieved a lock with that bandwidth so far - wait for osc-freq to update 1214 if (state->timf == 0) 1215 msleep(200); 1216 1217 /* offset loop parameters */ 1218 1219 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ 1220 tmp = (6 << 8) | 0x80; 1221 switch (ch->u.ofdm.transmission_mode) { 1222 case TRANSMISSION_MODE_2K: 1223 tmp |= (2 << 12); 1224 break; 1225 case TRANSMISSION_MODE_4K: 1226 tmp |= (3 << 12); 1227 break; 1228 default: 1229 case TRANSMISSION_MODE_8K: 1230 tmp |= (4 << 12); 1231 break; 1232 } 1233 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */ 1234 1235 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ 1236 tmp = (0 << 4); 1237 switch (ch->u.ofdm.transmission_mode) { 1238 case TRANSMISSION_MODE_2K: 1239 tmp |= 0x6; 1240 break; 1241 case TRANSMISSION_MODE_4K: 1242 tmp |= 0x7; 1243 break; 1244 default: 1245 case TRANSMISSION_MODE_8K: 1246 tmp |= 0x8; 1247 break; 1248 } 1249 dib7000p_write_word(state, 32, tmp); 1250 1251 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ 1252 tmp = (0 << 4); 1253 switch (ch->u.ofdm.transmission_mode) { 1254 case TRANSMISSION_MODE_2K: 1255 tmp |= 0x6; 1256 break; 1257 case TRANSMISSION_MODE_4K: 1258 tmp |= 0x7; 1259 break; 1260 default: 1261 case TRANSMISSION_MODE_8K: 1262 tmp |= 0x8; 1263 break; 1264 } 1265 dib7000p_write_word(state, 33, tmp); 1266 1267 tmp = dib7000p_read_word(state, 509); 1268 if (!((tmp >> 6) & 0x1)) { 1269 /* restart the fec */ 1270 tmp = dib7000p_read_word(state, 771); 1271 dib7000p_write_word(state, 771, tmp | (1 << 1)); 1272 dib7000p_write_word(state, 771, tmp); 1273 msleep(40); 1274 tmp = dib7000p_read_word(state, 509); 1275 } 1276 // we achieved a lock - it's time to update the osc freq 1277 if ((tmp >> 6) & 0x1) { 1278 dib7000p_update_timf(state); 1279 /* P_timf_alpha += 2 */ 1280 tmp = dib7000p_read_word(state, 26); 1281 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12)); 1282 } 1283 1284 if (state->cfg.spur_protect) 1285 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); 1286 1287 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); 1288 return 0; 1289} 1290 1291static int dib7000p_wakeup(struct dvb_frontend *demod) 1292{ 1293 struct dib7000p_state *state = demod->demodulator_priv; 1294 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 1295 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); 1296 if (state->version == SOC7090) 1297 dib7000p_sad_calib(state); 1298 return 0; 1299} 1300 1301static int dib7000p_sleep(struct dvb_frontend *demod) 1302{ 1303 struct dib7000p_state *state = demod->demodulator_priv; 1304 if (state->version == SOC7090) 1305 return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); 1306 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); 1307} 1308 1309static int dib7000p_identify(struct dib7000p_state *st) 1310{ 1311 u16 value; 1312 dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr); 1313 1314 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) { 1315 dprintk("wrong Vendor ID (read=0x%x)", value); 1316 return -EREMOTEIO; 1317 } 1318 1319 if ((value = dib7000p_read_word(st, 769)) != 0x4000) { 1320 dprintk("wrong Device ID (%x)", value); 1321 return -EREMOTEIO; 1322 } 1323 1324 return 0; 1325} 1326 1327static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 1328{ 1329 struct dib7000p_state *state = fe->demodulator_priv; 1330 u16 tps = dib7000p_read_word(state, 463); 1331 1332 fep->inversion = INVERSION_AUTO; 1333 1334 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth); 1335 1336 switch ((tps >> 8) & 0x3) { 1337 case 0: 1338 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; 1339 break; 1340 case 1: 1341 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; 1342 break; 1343 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */ 1344 } 1345 1346 switch (tps & 0x3) { 1347 case 0: 1348 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; 1349 break; 1350 case 1: 1351 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; 1352 break; 1353 case 2: 1354 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; 1355 break; 1356 case 3: 1357 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; 1358 break; 1359 } 1360 1361 switch ((tps >> 14) & 0x3) { 1362 case 0: 1363 fep->u.ofdm.constellation = QPSK; 1364 break; 1365 case 1: 1366 fep->u.ofdm.constellation = QAM_16; 1367 break; 1368 case 2: 1369 default: 1370 fep->u.ofdm.constellation = QAM_64; 1371 break; 1372 } 1373 1374 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ 1375 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */ 1376 1377 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; 1378 switch ((tps >> 5) & 0x7) { 1379 case 1: 1380 fep->u.ofdm.code_rate_HP = FEC_1_2; 1381 break; 1382 case 2: 1383 fep->u.ofdm.code_rate_HP = FEC_2_3; 1384 break; 1385 case 3: 1386 fep->u.ofdm.code_rate_HP = FEC_3_4; 1387 break; 1388 case 5: 1389 fep->u.ofdm.code_rate_HP = FEC_5_6; 1390 break; 1391 case 7: 1392 default: 1393 fep->u.ofdm.code_rate_HP = FEC_7_8; 1394 break; 1395 1396 } 1397 1398 switch ((tps >> 2) & 0x7) { 1399 case 1: 1400 fep->u.ofdm.code_rate_LP = FEC_1_2; 1401 break; 1402 case 2: 1403 fep->u.ofdm.code_rate_LP = FEC_2_3; 1404 break; 1405 case 3: 1406 fep->u.ofdm.code_rate_LP = FEC_3_4; 1407 break; 1408 case 5: 1409 fep->u.ofdm.code_rate_LP = FEC_5_6; 1410 break; 1411 case 7: 1412 default: 1413 fep->u.ofdm.code_rate_LP = FEC_7_8; 1414 break; 1415 } 1416 1417 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */ 1418 1419 return 0; 1420} 1421 1422static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 1423{ 1424 struct dib7000p_state *state = fe->demodulator_priv; 1425 int time, ret; 1426 1427 if (state->version == SOC7090) { 1428 dib7090_set_diversity_in(fe, 0); 1429 dib7090_set_output_mode(fe, OUTMODE_HIGH_Z); 1430 } else 1431 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); 1432 1433 /* maybe the parameter has been changed */ 1434 state->sfn_workaround_active = buggy_sfn_workaround; 1435 1436 if (fe->ops.tuner_ops.set_params) 1437 fe->ops.tuner_ops.set_params(fe, fep); 1438 1439 /* start up the AGC */ 1440 state->agc_state = 0; 1441 do { 1442 time = dib7000p_agc_startup(fe, fep); 1443 if (time != -1) 1444 msleep(time); 1445 } while (time != -1); 1446 1447 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || 1448 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) { 1449 int i = 800, found; 1450 1451 dib7000p_autosearch_start(fe, fep); 1452 do { 1453 msleep(1); 1454 found = dib7000p_autosearch_is_irq(fe); 1455 } while (found == 0 && i--); 1456 1457 dprintk("autosearch returns: %d", found); 1458 if (found == 0 || found == 1) 1459 return 0; 1460 1461 dib7000p_get_frontend(fe, fep); 1462 } 1463 1464 ret = dib7000p_tune(fe, fep); 1465 1466 /* make this a config parameter */ 1467 if (state->version == SOC7090) 1468 dib7090_set_output_mode(fe, state->cfg.output_mode); 1469 else 1470 dib7000p_set_output_mode(state, state->cfg.output_mode); 1471 1472 return ret; 1473} 1474 1475static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat) 1476{ 1477 struct dib7000p_state *state = fe->demodulator_priv; 1478 u16 lock = dib7000p_read_word(state, 509); 1479 1480 *stat = 0; 1481 1482 if (lock & 0x8000) 1483 *stat |= FE_HAS_SIGNAL; 1484 if (lock & 0x3000) 1485 *stat |= FE_HAS_CARRIER; 1486 if (lock & 0x0100) 1487 *stat |= FE_HAS_VITERBI; 1488 if (lock & 0x0010) 1489 *stat |= FE_HAS_SYNC; 1490 if ((lock & 0x0038) == 0x38) 1491 *stat |= FE_HAS_LOCK; 1492 1493 return 0; 1494} 1495 1496static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber) 1497{ 1498 struct dib7000p_state *state = fe->demodulator_priv; 1499 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501); 1500 return 0; 1501} 1502 1503static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) 1504{ 1505 struct dib7000p_state *state = fe->demodulator_priv; 1506 *unc = dib7000p_read_word(state, 506); 1507 return 0; 1508} 1509 1510static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength) 1511{ 1512 struct dib7000p_state *state = fe->demodulator_priv; 1513 u16 val = dib7000p_read_word(state, 394); 1514 *strength = 65535 - val; 1515 return 0; 1516} 1517 1518static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr) 1519{ 1520 struct dib7000p_state *state = fe->demodulator_priv; 1521 u16 val; 1522 s32 signal_mant, signal_exp, noise_mant, noise_exp; 1523 u32 result = 0; 1524 1525 val = dib7000p_read_word(state, 479); 1526 noise_mant = (val >> 4) & 0xff; 1527 noise_exp = ((val & 0xf) << 2); 1528 val = dib7000p_read_word(state, 480); 1529 noise_exp += ((val >> 14) & 0x3); 1530 if ((noise_exp & 0x20) != 0) 1531 noise_exp -= 0x40; 1532 1533 signal_mant = (val >> 6) & 0xFF; 1534 signal_exp = (val & 0x3F); 1535 if ((signal_exp & 0x20) != 0) 1536 signal_exp -= 0x40; 1537 1538 if (signal_mant != 0) 1539 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant); 1540 else 1541 result = intlog10(2) * 10 * signal_exp - 100; 1542 1543 if (noise_mant != 0) 1544 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant); 1545 else 1546 result -= intlog10(2) * 10 * noise_exp - 100; 1547 1548 *snr = result / ((1 << 24) / 10); 1549 return 0; 1550} 1551 1552static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) 1553{ 1554 tune->min_delay_ms = 1000; 1555 return 0; 1556} 1557 1558static void dib7000p_release(struct dvb_frontend *demod) 1559{ 1560 struct dib7000p_state *st = demod->demodulator_priv; 1561 dibx000_exit_i2c_master(&st->i2c_master); 1562 i2c_del_adapter(&st->dib7090_tuner_adap); 1563 kfree(st); 1564} 1565 1566int dib7000pc_detection(struct i2c_adapter *i2c_adap) 1567{ 1568 u8 *tx, *rx; 1569 struct i2c_msg msg[2] = { 1570 {.addr = 18 >> 1, .flags = 0, .len = 2}, 1571 {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2}, 1572 }; 1573 int ret = 0; 1574 1575 tx = kzalloc(2*sizeof(u8), GFP_KERNEL); 1576 if (!tx) 1577 return -ENOMEM; 1578 rx = kzalloc(2*sizeof(u8), GFP_KERNEL); 1579 if (!rx) { 1580 goto rx_memory_error; 1581 ret = -ENOMEM; 1582 } 1583 1584 msg[0].buf = tx; 1585 msg[1].buf = rx; 1586 1587 tx[0] = 0x03; 1588 tx[1] = 0x00; 1589 1590 if (i2c_transfer(i2c_adap, msg, 2) == 2) 1591 if (rx[0] == 0x01 && rx[1] == 0xb3) { 1592 dprintk("-D- DiB7000PC detected"); 1593 return 1; 1594 } 1595 1596 msg[0].addr = msg[1].addr = 0x40; 1597 1598 if (i2c_transfer(i2c_adap, msg, 2) == 2) 1599 if (rx[0] == 0x01 && rx[1] == 0xb3) { 1600 dprintk("-D- DiB7000PC detected"); 1601 return 1; 1602 } 1603 1604 dprintk("-D- DiB7000PC not detected"); 1605 1606 kfree(rx); 1607rx_memory_error: 1608 kfree(tx); 1609 return ret; 1610} 1611EXPORT_SYMBOL(dib7000pc_detection); 1612 1613struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating) 1614{ 1615 struct dib7000p_state *st = demod->demodulator_priv; 1616 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating); 1617} 1618EXPORT_SYMBOL(dib7000p_get_i2c_master); 1619 1620int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) 1621{ 1622 struct dib7000p_state *state = fe->demodulator_priv; 1623 u16 val = dib7000p_read_word(state, 235) & 0xffef; 1624 val |= (onoff & 0x1) << 4; 1625 dprintk("PID filter enabled %d", onoff); 1626 return dib7000p_write_word(state, 235, val); 1627} 1628EXPORT_SYMBOL(dib7000p_pid_filter_ctrl); 1629 1630int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) 1631{ 1632 struct dib7000p_state *state = fe->demodulator_priv; 1633 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff); 1634 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0); 1635} 1636EXPORT_SYMBOL(dib7000p_pid_filter); 1637 1638int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]) 1639{ 1640 struct dib7000p_state *dpst; 1641 int k = 0; 1642 u8 new_addr = 0; 1643 1644 dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL); 1645 if (!dpst) 1646 return -ENOMEM; 1647 1648 dpst->i2c_adap = i2c; 1649 1650 for (k = no_of_demods - 1; k >= 0; k--) { 1651 dpst->cfg = cfg[k]; 1652 1653 /* designated i2c address */ 1654 if (cfg[k].default_i2c_addr != 0) 1655 new_addr = cfg[k].default_i2c_addr + (k << 1); 1656 else 1657 new_addr = (0x40 + k) << 1; 1658 dpst->i2c_addr = new_addr; 1659 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */ 1660 if (dib7000p_identify(dpst) != 0) { 1661 dpst->i2c_addr = default_addr; 1662 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */ 1663 if (dib7000p_identify(dpst) != 0) { 1664 dprintk("DiB7000P #%d: not identified\n", k); 1665 kfree(dpst); 1666 return -EIO; 1667 } 1668 } 1669 1670 /* start diversity to pull_down div_str - just for i2c-enumeration */ 1671 dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY); 1672 1673 /* set new i2c address and force divstart */ 1674 dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2); 1675 1676 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr); 1677 } 1678 1679 for (k = 0; k < no_of_demods; k++) { 1680 dpst->cfg = cfg[k]; 1681 if (cfg[k].default_i2c_addr != 0) 1682 dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1; 1683 else 1684 dpst->i2c_addr = (0x40 + k) << 1; 1685 1686 // unforce divstr 1687 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2); 1688 1689 /* deactivate div - it was just for i2c-enumeration */ 1690 dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z); 1691 } 1692 1693 kfree(dpst); 1694 return 0; 1695} 1696EXPORT_SYMBOL(dib7000p_i2c_enumeration); 1697 1698static const s32 lut_1000ln_mant[] = { 1699 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600 1700}; 1701 1702static s32 dib7000p_get_adc_power(struct dvb_frontend *fe) 1703{ 1704 struct dib7000p_state *state = fe->demodulator_priv; 1705 u32 tmp_val = 0, exp = 0, mant = 0; 1706 s32 pow_i; 1707 u16 buf[2]; 1708 u8 ix = 0; 1709 1710 buf[0] = dib7000p_read_word(state, 0x184); 1711 buf[1] = dib7000p_read_word(state, 0x185); 1712 pow_i = (buf[0] << 16) | buf[1]; 1713 dprintk("raw pow_i = %d", pow_i); 1714 1715 tmp_val = pow_i; 1716 while (tmp_val >>= 1) 1717 exp++; 1718 1719 mant = (pow_i * 1000 / (1 << exp)); 1720 dprintk(" mant = %d exp = %d", mant / 1000, exp); 1721 1722 ix = (u8) ((mant - 1000) / 100); /* index of the LUT */ 1723 dprintk(" ix = %d", ix); 1724 1725 pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908); 1726 pow_i = (pow_i << 8) / 1000; 1727 dprintk(" pow_i = %d", pow_i); 1728 1729 return pow_i; 1730} 1731 1732static int map_addr_to_serpar_number(struct i2c_msg *msg) 1733{ 1734 if ((msg->buf[0] <= 15)) 1735 msg->buf[0] -= 1; 1736 else if (msg->buf[0] == 17) 1737 msg->buf[0] = 15; 1738 else if (msg->buf[0] == 16) 1739 msg->buf[0] = 17; 1740 else if (msg->buf[0] == 19) 1741 msg->buf[0] = 16; 1742 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25) 1743 msg->buf[0] -= 3; 1744 else if (msg->buf[0] == 28) 1745 msg->buf[0] = 23; 1746 else 1747 return -EINVAL; 1748 return 0; 1749} 1750 1751static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) 1752{ 1753 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); 1754 u8 n_overflow = 1; 1755 u16 i = 1000; 1756 u16 serpar_num = msg[0].buf[0]; 1757 1758 while (n_overflow == 1 && i) { 1759 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1; 1760 i--; 1761 if (i == 0) 1762 dprintk("Tuner ITF: write busy (overflow)"); 1763 } 1764 dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f)); 1765 dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]); 1766 1767 return num; 1768} 1769 1770static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) 1771{ 1772 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); 1773 u8 n_overflow = 1, n_empty = 1; 1774 u16 i = 1000; 1775 u16 serpar_num = msg[0].buf[0]; 1776 u16 read_word; 1777 1778 while (n_overflow == 1 && i) { 1779 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1; 1780 i--; 1781 if (i == 0) 1782 dprintk("TunerITF: read busy (overflow)"); 1783 } 1784 dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f)); 1785 1786 i = 1000; 1787 while (n_empty == 1 && i) { 1788 n_empty = dib7000p_read_word(state, 1984) & 0x1; 1789 i--; 1790 if (i == 0) 1791 dprintk("TunerITF: read busy (empty)"); 1792 } 1793 read_word = dib7000p_read_word(state, 1987); 1794 msg[1].buf[0] = (read_word >> 8) & 0xff; 1795 msg[1].buf[1] = (read_word) & 0xff; 1796 1797 return num; 1798} 1799 1800static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) 1801{ 1802 if (map_addr_to_serpar_number(&msg[0]) == 0) { /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */ 1803 if (num == 1) { /* write */ 1804 return w7090p_tuner_write_serpar(i2c_adap, msg, 1); 1805 } else { /* read */ 1806 return w7090p_tuner_read_serpar(i2c_adap, msg, 2); 1807 } 1808 } 1809 return num; 1810} 1811 1812int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address) 1813{ 1814 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); 1815 u16 word; 1816 1817 if (num == 1) { /* write */ 1818 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2]))); 1819 } else { 1820 word = dib7000p_read_word(state, apb_address); 1821 msg[1].buf[0] = (word >> 8) & 0xff; 1822 msg[1].buf[1] = (word) & 0xff; 1823 } 1824 1825 return num; 1826} 1827 1828static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) 1829{ 1830 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); 1831 1832 u16 apb_address = 0, word; 1833 int i = 0; 1834 switch (msg[0].buf[0]) { 1835 case 0x12: 1836 apb_address = 1920; 1837 break; 1838 case 0x14: 1839 apb_address = 1921; 1840 break; 1841 case 0x24: 1842 apb_address = 1922; 1843 break; 1844 case 0x1a: 1845 apb_address = 1923; 1846 break; 1847 case 0x22: 1848 apb_address = 1924; 1849 break; 1850 case 0x33: 1851 apb_address = 1926; 1852 break; 1853 case 0x34: 1854 apb_address = 1927; 1855 break; 1856 case 0x35: 1857 apb_address = 1928; 1858 break; 1859 case 0x36: 1860 apb_address = 1929; 1861 break; 1862 case 0x37: 1863 apb_address = 1930; 1864 break; 1865 case 0x38: 1866 apb_address = 1931; 1867 break; 1868 case 0x39: 1869 apb_address = 1932; 1870 break; 1871 case 0x2a: 1872 apb_address = 1935; 1873 break; 1874 case 0x2b: 1875 apb_address = 1936; 1876 break; 1877 case 0x2c: 1878 apb_address = 1937; 1879 break; 1880 case 0x2d: 1881 apb_address = 1938; 1882 break; 1883 case 0x2e: 1884 apb_address = 1939; 1885 break; 1886 case 0x2f: 1887 apb_address = 1940; 1888 break; 1889 case 0x30: 1890 apb_address = 1941; 1891 break; 1892 case 0x31: 1893 apb_address = 1942; 1894 break; 1895 case 0x32: 1896 apb_address = 1943; 1897 break; 1898 case 0x3e: 1899 apb_address = 1944; 1900 break; 1901 case 0x3f: 1902 apb_address = 1945; 1903 break; 1904 case 0x40: 1905 apb_address = 1948; 1906 break; 1907 case 0x25: 1908 apb_address = 914; 1909 break; 1910 case 0x26: 1911 apb_address = 915; 1912 break; 1913 case 0x27: 1914 apb_address = 916; 1915 break; 1916 case 0x28: 1917 apb_address = 917; 1918 break; 1919 case 0x1d: 1920 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3); 1921 word = dib7000p_read_word(state, 384 + i); 1922 msg[1].buf[0] = (word >> 8) & 0xff; 1923 msg[1].buf[1] = (word) & 0xff; 1924 return num; 1925 case 0x1f: 1926 if (num == 1) { /* write */ 1927 word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]); 1928 word &= 0x3; 1929 word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12); 1930 dib7000p_write_word(state, 72, word); /* Set the proper input */ 1931 return num; 1932 } 1933 } 1934 1935 if (apb_address != 0) /* R/W acces via APB */ 1936 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address); 1937 else /* R/W access via SERPAR */ 1938 return w7090p_tuner_rw_serpar(i2c_adap, msg, num); 1939 1940 return 0; 1941} 1942 1943static u32 dib7000p_i2c_func(struct i2c_adapter *adapter) 1944{ 1945 return I2C_FUNC_I2C; 1946} 1947 1948static struct i2c_algorithm dib7090_tuner_xfer_algo = { 1949 .master_xfer = dib7090_tuner_xfer, 1950 .functionality = dib7000p_i2c_func, 1951}; 1952 1953struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe) 1954{ 1955 struct dib7000p_state *st = fe->demodulator_priv; 1956 return &st->dib7090_tuner_adap; 1957} 1958EXPORT_SYMBOL(dib7090_get_i2c_tuner); 1959 1960static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive) 1961{ 1962 u16 reg; 1963 1964 /* drive host bus 2, 3, 4 */ 1965 reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12)); 1966 reg |= (drive << 12) | (drive << 6) | drive; 1967 dib7000p_write_word(state, 1798, reg); 1968 1969 /* drive host bus 5,6 */ 1970 reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8)); 1971 reg |= (drive << 8) | (drive << 2); 1972 dib7000p_write_word(state, 1799, reg); 1973 1974 /* drive host bus 7, 8, 9 */ 1975 reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12)); 1976 reg |= (drive << 12) | (drive << 6) | drive; 1977 dib7000p_write_word(state, 1800, reg); 1978 1979 /* drive host bus 10, 11 */ 1980 reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8)); 1981 reg |= (drive << 8) | (drive << 2); 1982 dib7000p_write_word(state, 1801, reg); 1983 1984 /* drive host bus 12, 13, 14 */ 1985 reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12)); 1986 reg |= (drive << 12) | (drive << 6) | drive; 1987 dib7000p_write_word(state, 1802, reg); 1988 1989 return 0; 1990} 1991 1992static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize) 1993{ 1994 u32 quantif = 3; 1995 u32 nom = (insertExtSynchro * P_Kin + syncSize); 1996 u32 denom = P_Kout; 1997 u32 syncFreq = ((nom << quantif) / denom); 1998 1999 if ((syncFreq & ((1 << quantif) - 1)) != 0) 2000 syncFreq = (syncFreq >> quantif) + 1; 2001 else 2002 syncFreq = (syncFreq >> quantif); 2003 2004 if (syncFreq != 0) 2005 syncFreq = syncFreq - 1; 2006 2007 return syncFreq; 2008} 2009 2010static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize) 2011{ 2012 u8 index_buf; 2013 u16 rx_copy_buf[22]; 2014 2015 dprintk("Configure DibStream Tx"); 2016 for (index_buf = 0; index_buf < 22; index_buf++) 2017 rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf); 2018 2019 dib7000p_write_word(state, 1615, 1); 2020 dib7000p_write_word(state, 1603, P_Kin); 2021 dib7000p_write_word(state, 1605, P_Kout); 2022 dib7000p_write_word(state, 1606, insertExtSynchro); 2023 dib7000p_write_word(state, 1608, synchroMode); 2024 dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff); 2025 dib7000p_write_word(state, 1610, syncWord & 0xffff); 2026 dib7000p_write_word(state, 1612, syncSize); 2027 dib7000p_write_word(state, 1615, 0); 2028 2029 for (index_buf = 0; index_buf < 22; index_buf++) 2030 dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]); 2031 2032 return 0; 2033} 2034 2035static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize, 2036 u32 dataOutRate) 2037{ 2038 u32 syncFreq; 2039 2040 dprintk("Configure DibStream Rx"); 2041 if ((P_Kin != 0) && (P_Kout != 0)) { 2042 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize); 2043 dib7000p_write_word(state, 1542, syncFreq); 2044 } 2045 dib7000p_write_word(state, 1554, 1); 2046 dib7000p_write_word(state, 1536, P_Kin); 2047 dib7000p_write_word(state, 1537, P_Kout); 2048 dib7000p_write_word(state, 1539, synchroMode); 2049 dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff); 2050 dib7000p_write_word(state, 1541, syncWord & 0xffff); 2051 dib7000p_write_word(state, 1543, syncSize); 2052 dib7000p_write_word(state, 1544, dataOutRate); 2053 dib7000p_write_word(state, 1554, 0); 2054 2055 return 0; 2056} 2057 2058static int dib7090_enDivOnHostBus(struct dib7000p_state *state) 2059{ 2060 u16 reg; 2061 2062 dprintk("Enable Diversity on host bus"); 2063 reg = (1 << 8) | (1 << 5); 2064 dib7000p_write_word(state, 1288, reg); 2065 2066 return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); 2067} 2068 2069static int dib7090_enAdcOnHostBus(struct dib7000p_state *state) 2070{ 2071 u16 reg; 2072 2073 dprintk("Enable ADC on host bus"); 2074 reg = (1 << 7) | (1 << 5); 2075 dib7000p_write_word(state, 1288, reg); 2076 2077 return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); 2078} 2079 2080static int dib7090_enMpegOnHostBus(struct dib7000p_state *state) 2081{ 2082 u16 reg; 2083 2084 dprintk("Enable Mpeg on host bus"); 2085 reg = (1 << 9) | (1 << 5); 2086 dib7000p_write_word(state, 1288, reg); 2087 2088 return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); 2089} 2090 2091static int dib7090_enMpegInput(struct dib7000p_state *state) 2092{ 2093 dprintk("Enable Mpeg input"); 2094 return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ 2095} 2096 2097static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) 2098{ 2099 u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1); 2100 2101 dprintk("Enable Mpeg mux"); 2102 dib7000p_write_word(state, 1287, reg); 2103 2104 reg &= ~(1 << 7); 2105 dib7000p_write_word(state, 1287, reg); 2106 2107 reg = (1 << 4); 2108 dib7000p_write_word(state, 1288, reg); 2109 2110 return 0; 2111} 2112 2113static int dib7090_disableMpegMux(struct dib7000p_state *state) 2114{ 2115 u16 reg; 2116 2117 dprintk("Disable Mpeg mux"); 2118 dib7000p_write_word(state, 1288, 0); 2119 2120 reg = dib7000p_read_word(state, 1287); 2121 reg &= ~(1 << 7); 2122 dib7000p_write_word(state, 1287, reg); 2123 2124 return 0; 2125} 2126 2127static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode) 2128{ 2129 struct dib7000p_state *state = fe->demodulator_priv; 2130 2131 switch (mode) { 2132 case INPUT_MODE_DIVERSITY: 2133 dprintk("Enable diversity INPUT"); 2134 dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); 2135 break; 2136 case INPUT_MODE_MPEG: 2137 dprintk("Enable Mpeg INPUT"); 2138 dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ 2139 break; 2140 case INPUT_MODE_OFF: 2141 default: 2142 dprintk("Disable INPUT"); 2143 dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0); 2144 break; 2145 } 2146 return 0; 2147} 2148 2149static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) 2150{ 2151 switch (onoff) { 2152 case 0: /* only use the internal way - not the diversity input */ 2153 dib7090_set_input_mode(fe, INPUT_MODE_MPEG); 2154 break; 2155 case 1: /* both ways */ 2156 case 2: /* only the diversity input */ 2157 dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY); 2158 break; 2159 } 2160 2161 return 0; 2162} 2163 2164static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) 2165{ 2166 struct dib7000p_state *state = fe->demodulator_priv; 2167 2168 u16 outreg, smo_mode, fifo_threshold; 2169 u8 prefer_mpeg_mux_use = 1; 2170 int ret = 0; 2171 2172 dib7090_host_bus_drive(state, 1); 2173 2174 fifo_threshold = 1792; 2175 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1); 2176 outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1)); 2177 2178 switch (mode) { 2179 case OUTMODE_HIGH_Z: 2180 outreg = 0; 2181 break; 2182 2183 case OUTMODE_MPEG2_SERIAL: 2184 if (prefer_mpeg_mux_use) { 2185 dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux"); 2186 dib7090_enMpegOnHostBus(state); 2187 dib7090_enMpegInput(state); 2188 if (state->cfg.enMpegOutput == 1) 2189 dib7090_enMpegMux(state, 3, 1, 1); 2190 2191 } else { /* Use Smooth block */ 2192 dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc"); 2193 dib7090_disableMpegMux(state); 2194 dib7000p_write_word(state, 1288, (1 << 6)); 2195 outreg |= (2 << 6) | (0 << 1); 2196 } 2197 break; 2198 2199 case OUTMODE_MPEG2_PAR_GATED_CLK: 2200 if (prefer_mpeg_mux_use) { 2201 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux"); 2202 dib7090_enMpegOnHostBus(state); 2203 dib7090_enMpegInput(state); 2204 if (state->cfg.enMpegOutput == 1) 2205 dib7090_enMpegMux(state, 2, 0, 0); 2206 } else { /* Use Smooth block */ 2207 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block"); 2208 dib7090_disableMpegMux(state); 2209 dib7000p_write_word(state, 1288, (1 << 6)); 2210 outreg |= (0 << 6); 2211 } 2212 break; 2213 2214 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ 2215 dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block"); 2216 dib7090_disableMpegMux(state); 2217 dib7000p_write_word(state, 1288, (1 << 6)); 2218 outreg |= (1 << 6); 2219 break; 2220 2221 case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */ 2222 dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block"); 2223 dib7090_disableMpegMux(state); 2224 dib7000p_write_word(state, 1288, (1 << 6)); 2225 outreg |= (5 << 6); 2226 smo_mode |= (3 << 1); 2227 fifo_threshold = 512; 2228 break; 2229 2230 case OUTMODE_DIVERSITY: 2231 dprintk("Sip 7090P setting output mode MODE_DIVERSITY"); 2232 dib7090_disableMpegMux(state); 2233 dib7090_enDivOnHostBus(state); 2234 break; 2235 2236 case OUTMODE_ANALOG_ADC: 2237 dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC"); 2238 dib7090_enAdcOnHostBus(state); 2239 break; 2240 } 2241 2242 if (state->cfg.output_mpeg2_in_188_bytes) 2243 smo_mode |= (1 << 5); 2244 2245 ret |= dib7000p_write_word(state, 235, smo_mode); 2246 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ 2247 ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */ 2248 2249 return ret; 2250} 2251 2252int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) 2253{ 2254 struct dib7000p_state *state = fe->demodulator_priv; 2255 u16 en_cur_state; 2256 2257 dprintk("sleep dib7090: %d", onoff); 2258 2259 en_cur_state = dib7000p_read_word(state, 1922); 2260 2261 if (en_cur_state > 0xff) 2262 state->tuner_enable = en_cur_state; 2263 2264 if (onoff) 2265 en_cur_state &= 0x00ff; 2266 else { 2267 if (state->tuner_enable != 0) 2268 en_cur_state = state->tuner_enable; 2269 } 2270 2271 dib7000p_write_word(state, 1922, en_cur_state); 2272 2273 return 0; 2274} 2275EXPORT_SYMBOL(dib7090_tuner_sleep); 2276 2277int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) 2278{ 2279 dprintk("AGC restart callback: %d", restart); 2280 return 0; 2281} 2282EXPORT_SYMBOL(dib7090_agc_restart); 2283 2284int dib7090_get_adc_power(struct dvb_frontend *fe) 2285{ 2286 return dib7000p_get_adc_power(fe); 2287} 2288EXPORT_SYMBOL(dib7090_get_adc_power); 2289 2290int dib7090_slave_reset(struct dvb_frontend *fe) 2291{ 2292 struct dib7000p_state *state = fe->demodulator_priv; 2293 u16 reg; 2294 2295 reg = dib7000p_read_word(state, 1794); 2296 dib7000p_write_word(state, 1794, reg | (4 << 12)); 2297 2298 dib7000p_write_word(state, 1032, 0xffff); 2299 return 0; 2300} 2301EXPORT_SYMBOL(dib7090_slave_reset); 2302 2303static struct dvb_frontend_ops dib7000p_ops; 2304struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) 2305{ 2306 struct dvb_frontend *demod; 2307 struct dib7000p_state *st; 2308 st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL); 2309 if (st == NULL) 2310 return NULL; 2311 2312 memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config)); 2313 st->i2c_adap = i2c_adap; 2314 st->i2c_addr = i2c_addr; 2315 st->gpio_val = cfg->gpio_val; 2316 st->gpio_dir = cfg->gpio_dir; 2317 2318 /* Ensure the output mode remains at the previous default if it's 2319 * not specifically set by the caller. 2320 */ 2321 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK)) 2322 st->cfg.output_mode = OUTMODE_MPEG2_FIFO; 2323 2324 demod = &st->demod; 2325 demod->demodulator_priv = st; 2326 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops)); 2327 2328 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */ 2329 2330 if (dib7000p_identify(st) != 0) 2331 goto error; 2332 2333 st->version = dib7000p_read_word(st, 897); 2334 2335 /* FIXME: make sure the dev.parent field is initialized, or else 2336 request_firmware() will hit an OOPS (this should be moved somewhere 2337 more common) */ 2338 2339 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); 2340 2341 /* init 7090 tuner adapter */ 2342 strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name)); 2343 st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo; 2344 st->dib7090_tuner_adap.algo_data = NULL; 2345 st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent; 2346 i2c_set_adapdata(&st->dib7090_tuner_adap, st); 2347 i2c_add_adapter(&st->dib7090_tuner_adap); 2348 2349 dib7000p_demod_reset(st); 2350 2351 if (st->version == SOC7090) { 2352 dib7090_set_output_mode(demod, st->cfg.output_mode); 2353 dib7090_set_diversity_in(demod, 0); 2354 } 2355 2356 return demod; 2357 2358error: 2359 kfree(st); 2360 return NULL; 2361} 2362EXPORT_SYMBOL(dib7000p_attach); 2363 2364static struct dvb_frontend_ops dib7000p_ops = { 2365 .info = { 2366 .name = "DiBcom 7000PC", 2367 .type = FE_OFDM, 2368 .frequency_min = 44250000, 2369 .frequency_max = 867250000, 2370 .frequency_stepsize = 62500, 2371 .caps = FE_CAN_INVERSION_AUTO | 2372 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 2373 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 2374 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 2375 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO, 2376 }, 2377 2378 .release = dib7000p_release, 2379 2380 .init = dib7000p_wakeup, 2381 .sleep = dib7000p_sleep, 2382 2383 .set_frontend = dib7000p_set_frontend, 2384 .get_tune_settings = dib7000p_fe_get_tune_settings, 2385 .get_frontend = dib7000p_get_frontend, 2386 2387 .read_status = dib7000p_read_status, 2388 .read_ber = dib7000p_read_ber, 2389 .read_signal_strength = dib7000p_read_signal_strength, 2390 .read_snr = dib7000p_read_snr, 2391 .read_ucblocks = dib7000p_read_unc_blocks, 2392}; 2393 2394MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>"); 2395MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 2396MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator"); 2397MODULE_LICENSE("GPL");