/drivers/media/dvb/frontends/dib8000.c
C | 2669 lines | 2103 code | 419 blank | 147 comment | 471 complexity | 94e638911f0533d70808edf3d38f4f05 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
1/* 2 * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T). 3 * 4 * Copyright (C) 2009 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#include <linux/mutex.h> 14 15#include "dvb_math.h" 16 17#include "dvb_frontend.h" 18 19#include "dib8000.h" 20 21#define LAYER_ALL -1 22#define LAYER_A 1 23#define LAYER_B 2 24#define LAYER_C 3 25 26#define FE_CALLBACK_TIME_NEVER 0xffffffff 27#define MAX_NUMBER_OF_FRONTENDS 6 28 29static int debug; 30module_param(debug, int, 0644); 31MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 32 33#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0) 34 35#define FE_STATUS_TUNE_FAILED 0 36 37struct i2c_device { 38 struct i2c_adapter *adap; 39 u8 addr; 40 u8 *i2c_write_buffer; 41 u8 *i2c_read_buffer; 42 struct mutex *i2c_buffer_lock; 43}; 44 45struct dib8000_state { 46 struct dib8000_config cfg; 47 48 struct i2c_device i2c; 49 50 struct dibx000_i2c_master i2c_master; 51 52 u16 wbd_ref; 53 54 u8 current_band; 55 u32 current_bandwidth; 56 struct dibx000_agc_config *current_agc; 57 u32 timf; 58 u32 timf_default; 59 60 u8 div_force_off:1; 61 u8 div_state:1; 62 u16 div_sync_wait; 63 64 u8 agc_state; 65 u8 differential_constellation; 66 u8 diversity_onoff; 67 68 s16 ber_monitored_layer; 69 u16 gpio_dir; 70 u16 gpio_val; 71 72 u16 revision; 73 u8 isdbt_cfg_loaded; 74 enum frontend_tune_state tune_state; 75 u32 status; 76 77 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS]; 78 79 /* for the I2C transfer */ 80 struct i2c_msg msg[2]; 81 u8 i2c_write_buffer[4]; 82 u8 i2c_read_buffer[2]; 83 struct mutex i2c_buffer_lock; 84}; 85 86enum dib8000_power_mode { 87 DIB8000M_POWER_ALL = 0, 88 DIB8000M_POWER_INTERFACE_ONLY, 89}; 90 91static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) 92{ 93 u16 ret; 94 struct i2c_msg msg[2] = { 95 {.addr = i2c->addr >> 1, .flags = 0, .len = 2}, 96 {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2}, 97 }; 98 99 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) { 100 dprintk("could not acquire lock"); 101 return 0; 102 } 103 104 msg[0].buf = i2c->i2c_write_buffer; 105 msg[0].buf[0] = reg >> 8; 106 msg[0].buf[1] = reg & 0xff; 107 msg[1].buf = i2c->i2c_read_buffer; 108 109 if (i2c_transfer(i2c->adap, msg, 2) != 2) 110 dprintk("i2c read error on %d", reg); 111 112 ret = (msg[1].buf[0] << 8) | msg[1].buf[1]; 113 mutex_unlock(i2c->i2c_buffer_lock); 114 return ret; 115} 116 117static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) 118{ 119 u16 ret; 120 121 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { 122 dprintk("could not acquire lock"); 123 return 0; 124 } 125 126 state->i2c_write_buffer[0] = reg >> 8; 127 state->i2c_write_buffer[1] = reg & 0xff; 128 129 memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); 130 state->msg[0].addr = state->i2c.addr >> 1; 131 state->msg[0].flags = 0; 132 state->msg[0].buf = state->i2c_write_buffer; 133 state->msg[0].len = 2; 134 state->msg[1].addr = state->i2c.addr >> 1; 135 state->msg[1].flags = I2C_M_RD; 136 state->msg[1].buf = state->i2c_read_buffer; 137 state->msg[1].len = 2; 138 139 if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2) 140 dprintk("i2c read error on %d", reg); 141 142 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; 143 mutex_unlock(&state->i2c_buffer_lock); 144 145 return ret; 146} 147 148static u32 dib8000_read32(struct dib8000_state *state, u16 reg) 149{ 150 u16 rw[2]; 151 152 rw[0] = dib8000_read_word(state, reg + 0); 153 rw[1] = dib8000_read_word(state, reg + 1); 154 155 return ((rw[0] << 16) | (rw[1])); 156} 157 158static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) 159{ 160 struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4}; 161 int ret = 0; 162 163 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) { 164 dprintk("could not acquire lock"); 165 return -EINVAL; 166 } 167 168 msg.buf = i2c->i2c_write_buffer; 169 msg.buf[0] = (reg >> 8) & 0xff; 170 msg.buf[1] = reg & 0xff; 171 msg.buf[2] = (val >> 8) & 0xff; 172 msg.buf[3] = val & 0xff; 173 174 ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 175 mutex_unlock(i2c->i2c_buffer_lock); 176 177 return ret; 178} 179 180static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val) 181{ 182 int ret; 183 184 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { 185 dprintk("could not acquire lock"); 186 return -EINVAL; 187 } 188 189 state->i2c_write_buffer[0] = (reg >> 8) & 0xff; 190 state->i2c_write_buffer[1] = reg & 0xff; 191 state->i2c_write_buffer[2] = (val >> 8) & 0xff; 192 state->i2c_write_buffer[3] = val & 0xff; 193 194 memset(&state->msg[0], 0, sizeof(struct i2c_msg)); 195 state->msg[0].addr = state->i2c.addr >> 1; 196 state->msg[0].flags = 0; 197 state->msg[0].buf = state->i2c_write_buffer; 198 state->msg[0].len = 4; 199 200 ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? 201 -EREMOTEIO : 0); 202 mutex_unlock(&state->i2c_buffer_lock); 203 204 return ret; 205} 206 207static const s16 coeff_2k_sb_1seg_dqpsk[8] = { 208 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c, 209 (920 << 5) | 0x09 210}; 211 212static const s16 coeff_2k_sb_1seg[8] = { 213 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f 214}; 215 216static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = { 217 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11, 218 (-931 << 5) | 0x0f 219}; 220 221static const s16 coeff_2k_sb_3seg_0dqpsk[8] = { 222 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e, 223 (982 << 5) | 0x0c 224}; 225 226static const s16 coeff_2k_sb_3seg_1dqpsk[8] = { 227 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12, 228 (-720 << 5) | 0x0d 229}; 230 231static const s16 coeff_2k_sb_3seg[8] = { 232 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e, 233 (-610 << 5) | 0x0a 234}; 235 236static const s16 coeff_4k_sb_1seg_dqpsk[8] = { 237 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f, 238 (-922 << 5) | 0x0d 239}; 240 241static const s16 coeff_4k_sb_1seg[8] = { 242 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d, 243 (-655 << 5) | 0x0a 244}; 245 246static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = { 247 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14, 248 (-958 << 5) | 0x13 249}; 250 251static const s16 coeff_4k_sb_3seg_0dqpsk[8] = { 252 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12, 253 (-568 << 5) | 0x0f 254}; 255 256static const s16 coeff_4k_sb_3seg_1dqpsk[8] = { 257 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14, 258 (-848 << 5) | 0x13 259}; 260 261static const s16 coeff_4k_sb_3seg[8] = { 262 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12, 263 (-869 << 5) | 0x13 264}; 265 266static const s16 coeff_8k_sb_1seg_dqpsk[8] = { 267 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13, 268 (-598 << 5) | 0x10 269}; 270 271static const s16 coeff_8k_sb_1seg[8] = { 272 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f, 273 (585 << 5) | 0x0f 274}; 275 276static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = { 277 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18, 278 (0 << 5) | 0x14 279}; 280 281static const s16 coeff_8k_sb_3seg_0dqpsk[8] = { 282 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15, 283 (-877 << 5) | 0x15 284}; 285 286static const s16 coeff_8k_sb_3seg_1dqpsk[8] = { 287 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18, 288 (-921 << 5) | 0x14 289}; 290 291static const s16 coeff_8k_sb_3seg[8] = { 292 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15, 293 (690 << 5) | 0x14 294}; 295 296static const s16 ana_fe_coeff_3seg[24] = { 297 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017 298}; 299 300static const s16 ana_fe_coeff_1seg[24] = { 301 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003 302}; 303 304static const s16 ana_fe_coeff_13seg[24] = { 305 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1 306}; 307 308static u16 fft_to_mode(struct dib8000_state *state) 309{ 310 u16 mode; 311 switch (state->fe[0]->dtv_property_cache.transmission_mode) { 312 case TRANSMISSION_MODE_2K: 313 mode = 1; 314 break; 315 case TRANSMISSION_MODE_4K: 316 mode = 2; 317 break; 318 default: 319 case TRANSMISSION_MODE_AUTO: 320 case TRANSMISSION_MODE_8K: 321 mode = 3; 322 break; 323 } 324 return mode; 325} 326 327static void dib8000_set_acquisition_mode(struct dib8000_state *state) 328{ 329 u16 nud = dib8000_read_word(state, 298); 330 nud |= (1 << 3) | (1 << 0); 331 dprintk("acquisition mode activated"); 332 dib8000_write_word(state, 298, nud); 333} 334static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode) 335{ 336 struct dib8000_state *state = fe->demodulator_priv; 337 338 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */ 339 340 outreg = 0; 341 fifo_threshold = 1792; 342 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); 343 344 dprintk("-I- Setting output mode for demod %p to %d", 345 &state->fe[0], mode); 346 347 switch (mode) { 348 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock 349 outreg = (1 << 10); /* 0x0400 */ 350 break; 351 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock 352 outreg = (1 << 10) | (1 << 6); /* 0x0440 */ 353 break; 354 case OUTMODE_MPEG2_SERIAL: // STBs with serial input 355 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */ 356 break; 357 case OUTMODE_DIVERSITY: 358 if (state->cfg.hostbus_diversity) { 359 outreg = (1 << 10) | (4 << 6); /* 0x0500 */ 360 sram &= 0xfdff; 361 } else 362 sram |= 0x0c00; 363 break; 364 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding 365 smo_mode |= (3 << 1); 366 fifo_threshold = 512; 367 outreg = (1 << 10) | (5 << 6); 368 break; 369 case OUTMODE_HIGH_Z: // disable 370 outreg = 0; 371 break; 372 373 case OUTMODE_ANALOG_ADC: 374 outreg = (1 << 10) | (3 << 6); 375 dib8000_set_acquisition_mode(state); 376 break; 377 378 default: 379 dprintk("Unhandled output_mode passed to be set for demod %p", 380 &state->fe[0]); 381 return -EINVAL; 382 } 383 384 if (state->cfg.output_mpeg2_in_188_bytes) 385 smo_mode |= (1 << 5); 386 387 dib8000_write_word(state, 299, smo_mode); 388 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */ 389 dib8000_write_word(state, 1286, outreg); 390 dib8000_write_word(state, 1291, sram); 391 392 return 0; 393} 394 395static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff) 396{ 397 struct dib8000_state *state = fe->demodulator_priv; 398 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0; 399 400 if (!state->differential_constellation) { 401 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1 402 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2 403 } else { 404 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0 405 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0 406 } 407 state->diversity_onoff = onoff; 408 409 switch (onoff) { 410 case 0: /* only use the internal way - not the diversity input */ 411 dib8000_write_word(state, 270, 1); 412 dib8000_write_word(state, 271, 0); 413 break; 414 case 1: /* both ways */ 415 dib8000_write_word(state, 270, 6); 416 dib8000_write_word(state, 271, 6); 417 break; 418 case 2: /* only the diversity input */ 419 dib8000_write_word(state, 270, 0); 420 dib8000_write_word(state, 271, 1); 421 break; 422 } 423 return 0; 424} 425 426static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode) 427{ 428 /* by default everything is going to be powered off */ 429 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, 430 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, 431 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; 432 433 /* now, depending on the requested mode, we power on */ 434 switch (mode) { 435 /* power up everything in the demod */ 436 case DIB8000M_POWER_ALL: 437 reg_774 = 0x0000; 438 reg_775 = 0x0000; 439 reg_776 = 0x0000; 440 reg_900 &= 0xfffc; 441 reg_1280 &= 0x00ff; 442 break; 443 case DIB8000M_POWER_INTERFACE_ONLY: 444 reg_1280 &= 0x00ff; 445 break; 446 } 447 448 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280); 449 dib8000_write_word(state, 774, reg_774); 450 dib8000_write_word(state, 775, reg_775); 451 dib8000_write_word(state, 776, reg_776); 452 dib8000_write_word(state, 900, reg_900); 453 dib8000_write_word(state, 1280, reg_1280); 454} 455 456static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no) 457{ 458 int ret = 0; 459 u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908); 460 461 switch (no) { 462 case DIBX000_SLOW_ADC_ON: 463 reg_908 |= (1 << 1) | (1 << 0); 464 ret |= dib8000_write_word(state, 908, reg_908); 465 reg_908 &= ~(1 << 1); 466 break; 467 468 case DIBX000_SLOW_ADC_OFF: 469 reg_908 |= (1 << 1) | (1 << 0); 470 break; 471 472 case DIBX000_ADC_ON: 473 reg_907 &= 0x0fff; 474 reg_908 &= 0x0003; 475 break; 476 477 case DIBX000_ADC_OFF: // leave the VBG voltage on 478 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12); 479 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2); 480 break; 481 482 case DIBX000_VBG_ENABLE: 483 reg_907 &= ~(1 << 15); 484 break; 485 486 case DIBX000_VBG_DISABLE: 487 reg_907 |= (1 << 15); 488 break; 489 490 default: 491 break; 492 } 493 494 ret |= dib8000_write_word(state, 907, reg_907); 495 ret |= dib8000_write_word(state, 908, reg_908); 496 497 return ret; 498} 499 500static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw) 501{ 502 struct dib8000_state *state = fe->demodulator_priv; 503 u32 timf; 504 505 if (bw == 0) 506 bw = 6000; 507 508 if (state->timf == 0) { 509 dprintk("using default timf"); 510 timf = state->timf_default; 511 } else { 512 dprintk("using updated timf"); 513 timf = state->timf; 514 } 515 516 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff)); 517 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff)); 518 519 return 0; 520} 521 522static int dib8000_sad_calib(struct dib8000_state *state) 523{ 524/* internal */ 525 dib8000_write_word(state, 923, (0 << 1) | (0 << 0)); 526 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096 527 528 /* do the calibration */ 529 dib8000_write_word(state, 923, (1 << 0)); 530 dib8000_write_word(state, 923, (0 << 0)); 531 532 msleep(1); 533 return 0; 534} 535 536int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value) 537{ 538 struct dib8000_state *state = fe->demodulator_priv; 539 if (value > 4095) 540 value = 4095; 541 state->wbd_ref = value; 542 return dib8000_write_word(state, 106, value); 543} 544 545EXPORT_SYMBOL(dib8000_set_wbd_ref); 546static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw) 547{ 548 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25); 549 dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */ 550 dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff)); 551 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff)); 552 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff)); 553 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003)); 554 555 dib8000_write_word(state, 922, bw->sad_cfg); 556} 557 558static void dib8000_reset_pll(struct dib8000_state *state) 559{ 560 const struct dibx000_bandwidth_config *pll = state->cfg.pll; 561 u16 clk_cfg1; 562 563 // clk_cfg0 564 dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0)); 565 566 // clk_cfg1 567 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | 568 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | 569 (pll->pll_range << 1) | (pll->pll_reset << 0); 570 571 dib8000_write_word(state, 902, clk_cfg1); 572 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); 573 dib8000_write_word(state, 902, clk_cfg1); 574 575 dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */ 576 577 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ 578 if (state->cfg.pll->ADClkSrc == 0) 579 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | 580 (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); 581 else if (state->cfg.refclksel != 0) 582 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | 583 ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | 584 (pll->ADClkSrc << 7) | (0 << 1)); 585 else 586 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); 587 588 dib8000_reset_pll_common(state, pll); 589} 590 591static int dib8000_reset_gpio(struct dib8000_state *st) 592{ 593 /* reset the GPIOs */ 594 dib8000_write_word(st, 1029, st->cfg.gpio_dir); 595 dib8000_write_word(st, 1030, st->cfg.gpio_val); 596 597 /* TODO 782 is P_gpio_od */ 598 599 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos); 600 601 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div); 602 return 0; 603} 604 605static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val) 606{ 607 st->cfg.gpio_dir = dib8000_read_word(st, 1029); 608 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */ 609 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */ 610 dib8000_write_word(st, 1029, st->cfg.gpio_dir); 611 612 st->cfg.gpio_val = dib8000_read_word(st, 1030); 613 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */ 614 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */ 615 dib8000_write_word(st, 1030, st->cfg.gpio_val); 616 617 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val); 618 619 return 0; 620} 621 622int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) 623{ 624 struct dib8000_state *state = fe->demodulator_priv; 625 return dib8000_cfg_gpio(state, num, dir, val); 626} 627 628EXPORT_SYMBOL(dib8000_set_gpio); 629static const u16 dib8000_defaults[] = { 630 /* auto search configuration - lock0 by default waiting 631 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */ 632 3, 7, 633 0x0004, 634 0x0400, 635 0x0814, 636 637 12, 11, 638 0x001b, 639 0x7740, 640 0x005b, 641 0x8d80, 642 0x01c9, 643 0xc380, 644 0x0000, 645 0x0080, 646 0x0000, 647 0x0090, 648 0x0001, 649 0xd4c0, 650 651 /*1, 32, 652 0x6680 // P_corm_thres Lock algorithms configuration */ 653 654 11, 80, /* set ADC level to -16 */ 655 (1 << 13) - 825 - 117, 656 (1 << 13) - 837 - 117, 657 (1 << 13) - 811 - 117, 658 (1 << 13) - 766 - 117, 659 (1 << 13) - 737 - 117, 660 (1 << 13) - 693 - 117, 661 (1 << 13) - 648 - 117, 662 (1 << 13) - 619 - 117, 663 (1 << 13) - 575 - 117, 664 (1 << 13) - 531 - 117, 665 (1 << 13) - 501 - 117, 666 667 4, 108, 668 0, 669 0, 670 0, 671 0, 672 673 1, 175, 674 0x0410, 675 1, 179, 676 8192, // P_fft_nb_to_cut 677 678 6, 181, 679 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800 680 0x2800, 681 0x2800, 682 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800 683 0x2800, 684 0x2800, 685 686 2, 193, 687 0x0666, // P_pha3_thres 688 0x0000, // P_cti_use_cpe, P_cti_use_prog 689 690 2, 205, 691 0x200f, // P_cspu_regul, P_cspu_win_cut 692 0x000f, // P_des_shift_work 693 694 5, 215, 695 0x023d, // P_adp_regul_cnt 696 0x00a4, // P_adp_noise_cnt 697 0x00a4, // P_adp_regul_ext 698 0x7ff0, // P_adp_noise_ext 699 0x3ccc, // P_adp_fil 700 701 1, 230, 702 0x0000, // P_2d_byp_ti_num 703 704 1, 263, 705 0x800, //P_equal_thres_wgn 706 707 1, 268, 708 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode 709 710 1, 270, 711 0x0001, // P_div_lock0_wait 712 1, 285, 713 0x0020, //p_fec_ 714 1, 299, 715 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */ 716 717 1, 338, 718 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1 719 (1 << 10) | 720 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */ 721 (3 << 5) | /* P_ctrl_pre_freq_step=3 */ 722 (1 << 0), /* P_pre_freq_win_len=1 */ 723 724 1, 903, 725 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) 726 727 0, 728}; 729 730static u16 dib8000_identify(struct i2c_device *client) 731{ 732 u16 value; 733 734 //because of glitches sometimes 735 value = dib8000_i2c_read16(client, 896); 736 737 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) { 738 dprintk("wrong Vendor ID (read=0x%x)", value); 739 return 0; 740 } 741 742 value = dib8000_i2c_read16(client, 897); 743 if (value != 0x8000 && value != 0x8001 && value != 0x8002) { 744 dprintk("wrong Device ID (%x)", value); 745 return 0; 746 } 747 748 switch (value) { 749 case 0x8000: 750 dprintk("found DiB8000A"); 751 break; 752 case 0x8001: 753 dprintk("found DiB8000B"); 754 break; 755 case 0x8002: 756 dprintk("found DiB8000C"); 757 break; 758 } 759 return value; 760} 761 762static int dib8000_reset(struct dvb_frontend *fe) 763{ 764 struct dib8000_state *state = fe->demodulator_priv; 765 766 dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */ 767 768 if ((state->revision = dib8000_identify(&state->i2c)) == 0) 769 return -EINVAL; 770 771 if (state->revision == 0x8000) 772 dprintk("error : dib8000 MA not supported"); 773 774 dibx000_reset_i2c_master(&state->i2c_master); 775 776 dib8000_set_power_mode(state, DIB8000M_POWER_ALL); 777 778 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */ 779 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE); 780 781 /* restart all parts */ 782 dib8000_write_word(state, 770, 0xffff); 783 dib8000_write_word(state, 771, 0xffff); 784 dib8000_write_word(state, 772, 0xfffc); 785 dib8000_write_word(state, 898, 0x000c); // sad 786 dib8000_write_word(state, 1280, 0x004d); 787 dib8000_write_word(state, 1281, 0x000c); 788 789 dib8000_write_word(state, 770, 0x0000); 790 dib8000_write_word(state, 771, 0x0000); 791 dib8000_write_word(state, 772, 0x0000); 792 dib8000_write_word(state, 898, 0x0004); // sad 793 dib8000_write_word(state, 1280, 0x0000); 794 dib8000_write_word(state, 1281, 0x0000); 795 796 /* drives */ 797 if (state->cfg.drives) 798 dib8000_write_word(state, 906, state->cfg.drives); 799 else { 800 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal."); 801 dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust 802 } 803 804 dib8000_reset_pll(state); 805 806 if (dib8000_reset_gpio(state) != 0) 807 dprintk("GPIO reset was not successful."); 808 809 if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0) 810 dprintk("OUTPUT_MODE could not be resetted."); 811 812 state->current_agc = NULL; 813 814 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ... 815 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */ 816 if (state->cfg.pll->ifreq == 0) 817 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */ 818 else 819 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */ 820 821 { 822 u16 l = 0, r; 823 const u16 *n; 824 n = dib8000_defaults; 825 l = *n++; 826 while (l) { 827 r = *n++; 828 do { 829 dib8000_write_word(state, r, *n++); 830 r++; 831 } while (--l); 832 l = *n++; 833 } 834 } 835 state->isdbt_cfg_loaded = 0; 836 837 //div_cfg override for special configs 838 if (state->cfg.div_cfg != 0) 839 dib8000_write_word(state, 903, state->cfg.div_cfg); 840 841 /* unforce divstr regardless whether i2c enumeration was done or not */ 842 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1)); 843 844 dib8000_set_bandwidth(fe, 6000); 845 846 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); 847 dib8000_sad_calib(state); 848 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF); 849 850 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); 851 852 return 0; 853} 854 855static void dib8000_restart_agc(struct dib8000_state *state) 856{ 857 // P_restart_iqc & P_restart_agc 858 dib8000_write_word(state, 770, 0x0a00); 859 dib8000_write_word(state, 770, 0x0000); 860} 861 862static int dib8000_update_lna(struct dib8000_state *state) 863{ 864 u16 dyn_gain; 865 866 if (state->cfg.update_lna) { 867 // read dyn_gain here (because it is demod-dependent and not tuner) 868 dyn_gain = dib8000_read_word(state, 390); 869 870 if (state->cfg.update_lna(state->fe[0], dyn_gain)) { 871 dib8000_restart_agc(state); 872 return 1; 873 } 874 } 875 return 0; 876} 877 878static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) 879{ 880 struct dibx000_agc_config *agc = NULL; 881 int i; 882 if (state->current_band == band && state->current_agc != NULL) 883 return 0; 884 state->current_band = band; 885 886 for (i = 0; i < state->cfg.agc_config_count; i++) 887 if (state->cfg.agc[i].band_caps & band) { 888 agc = &state->cfg.agc[i]; 889 break; 890 } 891 892 if (agc == NULL) { 893 dprintk("no valid AGC configuration found for band 0x%02x", band); 894 return -EINVAL; 895 } 896 897 state->current_agc = agc; 898 899 /* AGC */ 900 dib8000_write_word(state, 76, agc->setup); 901 dib8000_write_word(state, 77, agc->inv_gain); 902 dib8000_write_word(state, 78, agc->time_stabiliz); 903 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock); 904 905 // Demod AGC loop configuration 906 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp); 907 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp); 908 909 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d", 910 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); 911 912 /* AGC continued */ 913 if (state->wbd_ref != 0) 914 dib8000_write_word(state, 106, state->wbd_ref); 915 else // use default 916 dib8000_write_word(state, 106, agc->wbd_ref); 917 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); 918 dib8000_write_word(state, 108, agc->agc1_max); 919 dib8000_write_word(state, 109, agc->agc1_min); 920 dib8000_write_word(state, 110, agc->agc2_max); 921 dib8000_write_word(state, 111, agc->agc2_min); 922 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2); 923 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2); 924 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2); 925 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); 926 927 dib8000_write_word(state, 75, agc->agc1_pt3); 928 dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */ 929 930 return 0; 931} 932 933void dib8000_pwm_agc_reset(struct dvb_frontend *fe) 934{ 935 struct dib8000_state *state = fe->demodulator_priv; 936 dib8000_set_adc_state(state, DIBX000_ADC_ON); 937 dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))); 938} 939EXPORT_SYMBOL(dib8000_pwm_agc_reset); 940 941static int dib8000_agc_soft_split(struct dib8000_state *state) 942{ 943 u16 agc, split_offset; 944 945 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0) 946 return FE_CALLBACK_TIME_NEVER; 947 948 // n_agc_global 949 agc = dib8000_read_word(state, 390); 950 951 if (agc > state->current_agc->split.min_thres) 952 split_offset = state->current_agc->split.min; 953 else if (agc < state->current_agc->split.max_thres) 954 split_offset = state->current_agc->split.max; 955 else 956 split_offset = state->current_agc->split.max * 957 (agc - state->current_agc->split.min_thres) / 958 (state->current_agc->split.max_thres - state->current_agc->split.min_thres); 959 960 dprintk("AGC split_offset: %d", split_offset); 961 962 // P_agc_force_split and P_agc_split_offset 963 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset); 964 return 5000; 965} 966 967static int dib8000_agc_startup(struct dvb_frontend *fe) 968{ 969 struct dib8000_state *state = fe->demodulator_priv; 970 enum frontend_tune_state *tune_state = &state->tune_state; 971 972 int ret = 0; 973 974 switch (*tune_state) { 975 case CT_AGC_START: 976 // set power-up level: interf+analog+AGC 977 978 dib8000_set_adc_state(state, DIBX000_ADC_ON); 979 980 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) { 981 *tune_state = CT_AGC_STOP; 982 state->status = FE_STATUS_TUNE_FAILED; 983 break; 984 } 985 986 ret = 70; 987 *tune_state = CT_AGC_STEP_0; 988 break; 989 990 case CT_AGC_STEP_0: 991 //AGC initialization 992 if (state->cfg.agc_control) 993 state->cfg.agc_control(fe, 1); 994 995 dib8000_restart_agc(state); 996 997 // wait AGC rough lock time 998 ret = 50; 999 *tune_state = CT_AGC_STEP_1; 1000 break; 1001 1002 case CT_AGC_STEP_1: 1003 // wait AGC accurate lock time 1004 ret = 70; 1005 1006 if (dib8000_update_lna(state)) 1007 // wait only AGC rough lock time 1008 ret = 50; 1009 else 1010 *tune_state = CT_AGC_STEP_2; 1011 break; 1012 1013 case CT_AGC_STEP_2: 1014 dib8000_agc_soft_split(state); 1015 1016 if (state->cfg.agc_control) 1017 state->cfg.agc_control(fe, 0); 1018 1019 *tune_state = CT_AGC_STOP; 1020 break; 1021 default: 1022 ret = dib8000_agc_soft_split(state); 1023 break; 1024 } 1025 return ret; 1026 1027} 1028 1029static const s32 lut_1000ln_mant[] = 1030{ 1031 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 1032}; 1033 1034s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) 1035{ 1036 struct dib8000_state *state = fe->demodulator_priv; 1037 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0; 1038 s32 val; 1039 1040 val = dib8000_read32(state, 384); 1041 if (mode) { 1042 tmp_val = val; 1043 while (tmp_val >>= 1) 1044 exp++; 1045 mant = (val * 1000 / (1<<exp)); 1046 ix = (u8)((mant-1000)/100); /* index of the LUT */ 1047 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); 1048 val = (val*256)/1000; 1049 } 1050 return val; 1051} 1052EXPORT_SYMBOL(dib8000_get_adc_power); 1053 1054static void dib8000_update_timf(struct dib8000_state *state) 1055{ 1056 u32 timf = state->timf = dib8000_read32(state, 435); 1057 1058 dib8000_write_word(state, 29, (u16) (timf >> 16)); 1059 dib8000_write_word(state, 30, (u16) (timf & 0xffff)); 1060 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); 1061} 1062 1063static const u16 adc_target_16dB[11] = { 1064 (1 << 13) - 825 - 117, 1065 (1 << 13) - 837 - 117, 1066 (1 << 13) - 811 - 117, 1067 (1 << 13) - 766 - 117, 1068 (1 << 13) - 737 - 117, 1069 (1 << 13) - 693 - 117, 1070 (1 << 13) - 648 - 117, 1071 (1 << 13) - 619 - 117, 1072 (1 << 13) - 575 - 117, 1073 (1 << 13) - 531 - 117, 1074 (1 << 13) - 501 - 117 1075}; 1076static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 }; 1077 1078static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching) 1079{ 1080 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0; 1081 u8 guard, crate, constellation, timeI; 1082 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled 1083 const s16 *ncoeff = NULL, *ana_fe; 1084 u16 tmcc_pow = 0; 1085 u16 coff_pow = 0x2800; 1086 u16 init_prbs = 0xfff; 1087 u16 ana_gain = 0; 1088 1089 if (state->ber_monitored_layer != LAYER_ALL) 1090 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer); 1091 else 1092 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60); 1093 1094 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec 1095 dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i); 1096 1097 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { 1098 //compute new dds_freq for the seg and adjust prbs 1099 int seg_offset = 1100 state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx - 1101 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) - 1102 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2); 1103 int clk = state->cfg.pll->internal; 1104 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26) 1105 int dds_offset = seg_offset * segtodds; 1106 int new_dds, sub_channel; 1107 if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) 1108 dds_offset -= (int)(segtodds / 2); 1109 1110 if (state->cfg.pll->ifreq == 0) { 1111 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) { 1112 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1); 1113 new_dds = dds_offset; 1114 } else 1115 new_dds = dds_offset; 1116 1117 // We shift tuning frequency if the wanted segment is : 1118 // - the segment of center frequency with an odd total number of segments 1119 // - the segment to the left of center frequency with an even total number of segments 1120 // - the segment to the right of center frequency with an even total number of segments 1121 if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT) 1122 && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) 1123 && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) 1124 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == 1125 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) 1126 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) 1127 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2))) 1128 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) 1129 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == 1130 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) 1131 )) { 1132 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26) 1133 } 1134 } else { 1135 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) 1136 new_dds = state->cfg.pll->ifreq - dds_offset; 1137 else 1138 new_dds = state->cfg.pll->ifreq + dds_offset; 1139 } 1140 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff)); 1141 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff)); 1142 if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) 1143 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3; 1144 else 1145 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3; 1146 sub_channel -= 6; 1147 1148 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K 1149 || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) { 1150 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1 1151 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1 1152 } else { 1153 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0 1154 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0 1155 } 1156 1157 switch (state->fe[0]->dtv_property_cache.transmission_mode) { 1158 case TRANSMISSION_MODE_2K: 1159 switch (sub_channel) { 1160 case -6: 1161 init_prbs = 0x0; 1162 break; // 41, 0, 1 1163 case -5: 1164 init_prbs = 0x423; 1165 break; // 02~04 1166 case -4: 1167 init_prbs = 0x9; 1168 break; // 05~07 1169 case -3: 1170 init_prbs = 0x5C7; 1171 break; // 08~10 1172 case -2: 1173 init_prbs = 0x7A6; 1174 break; // 11~13 1175 case -1: 1176 init_prbs = 0x3D8; 1177 break; // 14~16 1178 case 0: 1179 init_prbs = 0x527; 1180 break; // 17~19 1181 case 1: 1182 init_prbs = 0x7FF; 1183 break; // 20~22 1184 case 2: 1185 init_prbs = 0x79B; 1186 break; // 23~25 1187 case 3: 1188 init_prbs = 0x3D6; 1189 break; // 26~28 1190 case 4: 1191 init_prbs = 0x3A2; 1192 break; // 29~31 1193 case 5: 1194 init_prbs = 0x53B; 1195 break; // 32~34 1196 case 6: 1197 init_prbs = 0x2F4; 1198 break; // 35~37 1199 default: 1200 case 7: 1201 init_prbs = 0x213; 1202 break; // 38~40 1203 } 1204 break; 1205 1206 case TRANSMISSION_MODE_4K: 1207 switch (sub_channel) { 1208 case -6: 1209 init_prbs = 0x0; 1210 break; // 41, 0, 1 1211 case -5: 1212 init_prbs = 0x208; 1213 break; // 02~04 1214 case -4: 1215 init_prbs = 0xC3; 1216 break; // 05~07 1217 case -3: 1218 init_prbs = 0x7B9; 1219 break; // 08~10 1220 case -2: 1221 init_prbs = 0x423; 1222 break; // 11~13 1223 case -1: 1224 init_prbs = 0x5C7; 1225 break; // 14~16 1226 case 0: 1227 init_prbs = 0x3D8; 1228 break; // 17~19 1229 case 1: 1230 init_prbs = 0x7FF; 1231 break; // 20~22 1232 case 2: 1233 init_prbs = 0x3D6; 1234 break; // 23~25 1235 case 3: 1236 init_prbs = 0x53B; 1237 break; // 26~28 1238 case 4: 1239 init_prbs = 0x213; 1240 break; // 29~31 1241 case 5: 1242 init_prbs = 0x29; 1243 break; // 32~34 1244 case 6: 1245 init_prbs = 0xD0; 1246 break; // 35~37 1247 default: 1248 case 7: 1249 init_prbs = 0x48E; 1250 break; // 38~40 1251 } 1252 break; 1253 1254 default: 1255 case TRANSMISSION_MODE_8K: 1256 switch (sub_channel) { 1257 case -6: 1258 init_prbs = 0x0; 1259 break; // 41, 0, 1 1260 case -5: 1261 init_prbs = 0x740; 1262 break; // 02~04 1263 case -4: 1264 init_prbs = 0x069; 1265 break; // 05~07 1266 case -3: 1267 init_prbs = 0x7DD; 1268 break; // 08~10 1269 case -2: 1270 init_prbs = 0x208; 1271 break; // 11~13 1272 case -1: 1273 init_prbs = 0x7B9; 1274 break; // 14~16 1275 case 0: 1276 init_prbs = 0x5C7; 1277 break; // 17~19 1278 case 1: 1279 init_prbs = 0x7FF; 1280 break; // 20~22 1281 case 2: 1282 init_prbs = 0x53B; 1283 break; // 23~25 1284 case 3: 1285 init_prbs = 0x29; 1286 break; // 26~28 1287 case 4: 1288 init_prbs = 0x48E; 1289 break; // 29~31 1290 case 5: 1291 init_prbs = 0x4C4; 1292 break; // 32~34 1293 case 6: 1294 init_prbs = 0x367; 1295 break; // 33~37 1296 default: 1297 case 7: 1298 init_prbs = 0x684; 1299 break; // 38~40 1300 } 1301 break; 1302 } 1303 } else { 1304 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff)); 1305 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff)); 1306 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003)); 1307 } 1308 /*P_mode == ?? */ 1309 dib8000_write_word(state, 10, (seq << 4)); 1310 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000); 1311 1312 switch (state->fe[0]->dtv_property_cache.guard_interval) { 1313 case GUARD_INTERVAL_1_32: 1314 guard = 0; 1315 break; 1316 case GUARD_INTERVAL_1_16: 1317 guard = 1; 1318 break; 1319 case GUARD_INTERVAL_1_8: 1320 guard = 2; 1321 break; 1322 case GUARD_INTERVAL_1_4: 1323 default: 1324 guard = 3; 1325 break; 1326 } 1327 1328 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1 1329 1330 max_constellation = DQPSK; 1331 for (i = 0; i < 3; i++) { 1332 switch (state->fe[0]->dtv_property_cache.layer[i].modulation) { 1333 case DQPSK: 1334 constellation = 0; 1335 break; 1336 case QPSK: 1337 constellation = 1; 1338 break; 1339 case QAM_16: 1340 constellation = 2; 1341 break; 1342 case QAM_64: 1343 default: 1344 constellation = 3; 1345 break; 1346 } 1347 1348 switch (state->fe[0]->dtv_property_cache.layer[i].fec) { 1349 case FEC_1_2: 1350 crate = 1; 1351 break; 1352 case FEC_2_3: 1353 crate = 2; 1354 break; 1355 case FEC_3_4: 1356 crate = 3; 1357 break; 1358 case FEC_5_6: 1359 crate = 5; 1360 break; 1361 case FEC_7_8: 1362 default: 1363 crate = 7; 1364 break; 1365 } 1366 1367 if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) && 1368 ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) || 1369 (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)) 1370 ) 1371 timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving; 1372 else 1373 timeI = 0; 1374 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) | 1375 (crate << 3) | timeI); 1376 if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) { 1377 switch (max_constellation) { 1378 case DQPSK: 1379 case QPSK: 1380 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 || 1381 state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64) 1382 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation; 1383 break; 1384 case QAM_16: 1385 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64) 1386 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation; 1387 break; 1388 } 1389 } 1390 } 1391 1392 mode = fft_to_mode(state); 1393 1394 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/ 1395 1396 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | 1397 ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache. 1398 isdbt_sb_mode & 1) << 4)); 1399 1400 dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval); 1401 1402 /* signal optimization parameter */ 1403 1404 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) { 1405 seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0]; 1406 for (i = 1; i < 3; i++) 1407 nbseg_diff += 1408 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count; 1409 for (i = 0; i < nbseg_diff; i++) 1410 seg_diff_mask |= 1 << permu_seg[i + 1]; 1411 } else { 1412 for (i = 0; i < 3; i++) 1413 nbseg_diff += 1414 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count; 1415 for (i = 0; i < nbseg_diff; i++) 1416 seg_diff_mask |= 1 << permu_seg[i]; 1417 } 1418 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); 1419 1420 state->differential_constellation = (seg_diff_mask != 0); 1421 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); 1422 1423 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 1424 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) 1425 seg_mask13 = 0x00E0; 1426 else // 1-segment 1427 seg_mask13 = 0x0040; 1428 } else 1429 seg_mask13 = 0x1fff; 1430 1431 // WRITE: Mode & Diff mask 1432 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask); 1433 1434 if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode)) 1435 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200); 1436 else 1437 dib8000_write_word(state, 268, (2 << 9) | 39); //init value 1438 1439 // ---- SMALL ---- 1440 // P_small_seg_diff 1441 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352 1442 1443 dib8000_write_word(state, 353, seg_mask13); // ADDR 353 1444 1445/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */ 1446 1447 // ---- SMALL ---- 1448 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 1449 switch (state->fe[0]->dtv_property_cache.transmission_mode) { 1450 case TRANSMISSION_MODE_2K: 1451 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { 1452 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) 1453 ncoeff = coeff_2k_sb_1seg_dqpsk; 1454 else // QPSK or QAM 1455 ncoeff = coeff_2k_sb_1seg; 1456 } else { // 3-segments 1457 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { 1458 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) 1459 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk; 1460 else // QPSK or QAM on external segments 1461 ncoeff = coeff_2k_sb_3seg_0dqpsk; 1462 } else { // QPSK or QAM on central segment 1463 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) 1464 ncoeff = coeff_2k_sb_3seg_1dqpsk; 1465 else // QPSK or QAM on external segments 1466 ncoeff = coeff_2k_sb_3seg; 1467 } 1468 } 1469 break; 1470 1471 case TRANSMISSION_MODE_4K: 1472 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { 1473 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) 1474 ncoeff = coeff_4k_sb_1seg_dqpsk; 1475 else // QPSK or QAM 1476 ncoeff = coeff_4k_sb_1seg; 1477 } else { // 3-segments 1478 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { 1479 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { 1480 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk; 1481 } else { // QPSK or QAM on external segments 1482 ncoeff = coeff_4k_sb_3seg_0dqpsk; 1483 } 1484 } else { // QPSK or QAM on central segment 1485 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { 1486 ncoeff = coeff_4k_sb_3seg_1dqpsk; 1487 } else // QPSK or QAM on external segments 1488 ncoeff = coeff_4k_sb_3seg; 1489 } 1490 } 1491 break; 1492 1493 case TRANSMISSION_MODE_AUTO: 1494 case TRANSMISSION_MODE_8K: 1495 default: 1496 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { 1497 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) 1498 ncoeff = coeff_8k_sb_1seg_dqpsk; 1499 else // QPSK or QAM 1500 ncoeff = coeff_8k_sb_1seg; 1501 } else { // 3-segments 1502 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { 1503 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { 1504 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk; 1505 } else { // QPSK or QAM on external segments 1506 ncoeff = coeff_8k_sb_3seg_0dqpsk; 1507 } 1508 } else { // QPSK or QAM on central segment 1509 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { 1510 ncoeff = coeff_8k_sb_3seg_1dqpsk; 1511 } else // QPSK or QAM on external segments 1512 ncoeff = coeff_8k_sb_3seg; 1513 } 1514 } 1515 break; 1516 } 1517 for (i = 0; i < 8; i++) 1518 dib8000_write_word(state, 343 + i, ncoeff[i]); 1519 } 1520 1521 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 1522 dib8000_write_word(state, 351, 1523 (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5); 1524 1525 // ---- COFF ---- 1526 // Carloff, the most robust 1527 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 1528 1529 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64 1530 // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1 1531 dib8000_write_word(state, 187, 1532 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2) 1533 | 0x3); 1534 1535/* // P_small_coef_ext_enable = 1 */ 1536/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */ 1537 1538 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { 1539 1540 // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1) 1541 if (mode == 3) 1542 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14)); 1543 else 1544 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14)); 1545 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1, 1546 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4 1547 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4); 1548 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8 1549 dib8000_write_word(state, 340, (16 << 6) | (8 << 0)); 1550 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1 1551 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); 1552 1553 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k 1554 dib8000_write_word(state, 181, 300); 1555 dib8000_write_word(state, 182, 150); 1556 dib8000_write_word(state, 183, 80); 1557 dib8000_write_word(state, 184, 300); 1558 dib8000_write_word(state, 185, 150); 1559 dib8000_write_word(state, 186, 80); 1560 } else { // Sound Broadcasting mode 3 seg 1561 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15 1562 /* if (mode == 3) */ 1563 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */ 1564 /* else */ 1565 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */ 1566 dib8000_write_word(state, 180, 0x1fcf | (1 << 14)); 1567 1568 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, 1569 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4 1570 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4); 1571 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8 1572 dib8000_write_word(state, 340, (16 << 6) | (8 << 0)); 1573 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1 1574 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); 1575 1576 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k 1577 dib8000_write_word(state, 181, 350); 1578 dib8000_write_word(state, 182, 300); 1579 dib8000_write_word(state, 183, 250); 1580 dib8000_write_word(state, 184, 350); 1581 dib8000_write_word(state, 185, 300); 1582 dib8000_write_word(state, 186, 250); 1583 } 1584 1585 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments 1586 dib8000_write_word(state, 180, (16 << 6) | 9); 1587 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2); 1588 coff_pow = 0x2800; 1589 for (i = 0; i < 6; i++) 1590 dib8000_write_word(state, 181 + i, coff_pow); 1591 1592 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1, 1593 // P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1 1594 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1); 1595 1596 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6 1597 dib8000_write_word(state, 340, (8 << 6) | (6 << 0)); 1598 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1 1599 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); 1600 } 1601 // ---- FFT ---- 1602 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) 1603 dib8000_write_word(state, 178, 64); // P_fft_powrange=64 1604 else 1605 dib8000_write_word(state, 178, 32); // P_fft_powrange=32 1606 1607 /* make the cpil_coff_lock more robust but slower p_coff_winlen 1608 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed) 1609 */ 1610 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13)) 1611 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */ 1612 1613 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */ 1614 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */ 1615 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */ 1616 if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0)) 1617 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */ 1618 else 1619 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */ 1620 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */ 1621 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */ 1622 if (!autosearching) 1623 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */ 1624 else 1625 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels. 1626 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000); 1627 1628 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */ 1629 1630 /* offset loop parameters */ 1631 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 1632 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) 1633 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */ 1634 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40); 1635 1636 else // Sound Broadcasting mode 3 seg 1637 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */ 1638 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60); 1639 } else 1640 // TODO in 13 seg, timf_alpha can always be the same or not ? 1641 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */ 1642 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80); 1643 1644 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode…
Large files files are truncated, but you can click here to view the full file