extractedLnx/linux-2.6.32/drivers/media/dvb/frontends/dib8000.c_dib8000_set_channel.c
static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
{
u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
u8 guard, crate, constellation, timeI;
u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
const s16 *ncoeff, *ana_fe;
u16 tmcc_pow = 0;
u16 coff_pow = 0x2800;
u16 init_prbs = 0xfff;
u16 ana_gain = 0;
u16 adc_target_16dB[11] = {
(1 << 13) - 825 - 117,
(1 << 13) - 837 - 117,
(1 << 13) - 811 - 117,
(1 << 13) - 766 - 117,
(1 << 13) - 737 - 117,
(1 << 13) - 693 - 117,
(1 << 13) - 648 - 117,
(1 << 13) - 619 - 117,
(1 << 13) - 575 - 117,
(1 << 13) - 531 - 117,
(1 << 13) - 501 - 117
};
if (state->ber_monitored_layer != LAYER_ALL)
dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
else
dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i);
if (state->fe.dtv_property_cache.isdbt_sb_mode) {
//compute new dds_freq for the seg and adjust prbs
int seg_offset =
state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) -
(state->fe.dtv_property_cache.isdbt_sb_segment_count % 2);
int clk = state->cfg.pll->internal;
u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
int dds_offset = seg_offset * segtodds;
int new_dds, sub_channel;
if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even
dds_offset -= (int)(segtodds / 2);
if (state->cfg.pll->ifreq == 0) {
if ((state->fe.dtv_property_cache.inversion ^ i) == 0) {
dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
new_dds = dds_offset;
} else
new_dds = dds_offset;
// We shift tuning frequency if the wanted segment is :
// - the segment of center frequency with an odd total number of segments
// - the segment to the left of center frequency with an even total number of segments
// - the segment to the right of center frequency with an even total number of segments
if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
&&
(((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)
&& (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
|| (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
&& (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2)))
|| (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
&& (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
)) {
new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
}
} else {
if ((state->fe.dtv_property_cache.inversion ^ i) == 0)
new_dds = state->cfg.pll->ifreq - dds_offset;
else
new_dds = state->cfg.pll->ifreq + dds_offset;
}
dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) // if odd
sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
else // if even
sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
sub_channel -= 6;
if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
|| state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
} else {
dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
}
switch (state->fe.dtv_property_cache.transmission_mode) {
case TRANSMISSION_MODE_2K:
switch (sub_channel) {
case -6:
init_prbs = 0x0;
break; // 41, 0, 1
case -5:
init_prbs = 0x423;
break; // 02~04
case -4:
init_prbs = 0x9;
break; // 05~07
case -3:
init_prbs = 0x5C7;
break; // 08~10
case -2:
init_prbs = 0x7A6;
break; // 11~13
case -1:
init_prbs = 0x3D8;
break; // 14~16
case 0:
init_prbs = 0x527;
break; // 17~19
case 1:
init_prbs = 0x7FF;
break; // 20~22
case 2:
init_prbs = 0x79B;
break; // 23~25
case 3:
init_prbs = 0x3D6;
break; // 26~28
case 4:
init_prbs = 0x3A2;
break; // 29~31
case 5:
init_prbs = 0x53B;
break; // 32~34
case 6:
init_prbs = 0x2F4;
break; // 35~37
default:
case 7:
init_prbs = 0x213;
break; // 38~40
}
break;
case TRANSMISSION_MODE_4K:
switch (sub_channel) {
case -6:
init_prbs = 0x0;
break; // 41, 0, 1
case -5:
init_prbs = 0x208;
break; // 02~04
case -4:
init_prbs = 0xC3;
break; // 05~07
case -3:
init_prbs = 0x7B9;
break; // 08~10
case -2:
init_prbs = 0x423;
break; // 11~13
case -1:
init_prbs = 0x5C7;
break; // 14~16
case 0:
init_prbs = 0x3D8;
break; // 17~19
case 1:
init_prbs = 0x7FF;
break; // 20~22
case 2:
init_prbs = 0x3D6;
break; // 23~25
case 3:
init_prbs = 0x53B;
break; // 26~28
case 4:
init_prbs = 0x213;
break; // 29~31
case 5:
init_prbs = 0x29;
break; // 32~34
case 6:
init_prbs = 0xD0;
break; // 35~37
default:
case 7:
init_prbs = 0x48E;
break; // 38~40
}
break;
default:
case TRANSMISSION_MODE_8K:
switch (sub_channel) {
case -6:
init_prbs = 0x0;
break; // 41, 0, 1
case -5:
init_prbs = 0x740;
break; // 02~04
case -4:
init_prbs = 0x069;
break; // 05~07
case -3:
init_prbs = 0x7DD;
break; // 08~10
case -2:
init_prbs = 0x208;
break; // 11~13
case -1:
init_prbs = 0x7B9;
break; // 14~16
case 0:
init_prbs = 0x5C7;
break; // 17~19
case 1:
init_prbs = 0x7FF;
break; // 20~22
case 2:
init_prbs = 0x53B;
break; // 23~25
case 3:
init_prbs = 0x29;
break; // 26~28
case 4:
init_prbs = 0x48E;
break; // 29~31
case 5:
init_prbs = 0x4C4;
break; // 32~34
case 6:
init_prbs = 0x367;
break; // 33~37
default:
case 7:
init_prbs = 0x684;
break; // 38~40
}
break;
}
} else { // if not state->fe.dtv_property_cache.isdbt_sb_mode
dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
}
/*P_mode == ?? */
dib8000_write_word(state, 10, (seq << 4));
// dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
switch (state->fe.dtv_property_cache.guard_interval) {
case GUARD_INTERVAL_1_32:
guard = 0;
break;
case GUARD_INTERVAL_1_16:
guard = 1;
break;
case GUARD_INTERVAL_1_8:
guard = 2;
break;
case GUARD_INTERVAL_1_4:
default:
guard = 3;
break;
}
dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
max_constellation = DQPSK;
for (i = 0; i < 3; i++) {
switch (state->fe.dtv_property_cache.layer[i].modulation) {
case DQPSK:
constellation = 0;
break;
case QPSK:
constellation = 1;
break;
case QAM_16:
constellation = 2;
break;
case QAM_64:
default:
constellation = 3;
break;
}
switch (state->fe.dtv_property_cache.layer[i].fec) {
case FEC_1_2:
crate = 1;
break;
case FEC_2_3:
crate = 2;
break;
case FEC_3_4:
crate = 3;
break;
case FEC_5_6:
crate = 5;
break;
case FEC_7_8:
default:
crate = 7;
break;
}
if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) &&
((state->fe.dtv_property_cache.layer[i].interleaving <= 3) ||
(state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1))
)
timeI = state->fe.dtv_property_cache.layer[i].interleaving;
else
timeI = 0;
dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
(crate << 3) | timeI);
if (state->fe.dtv_property_cache.layer[i].segment_count > 0) {
switch (max_constellation) {
case DQPSK:
case QPSK:
if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 ||
state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
break;
case QAM_16:
if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
break;
}
}
}
mode = fft_to_mode(state);
//dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache.
isdbt_sb_mode & 1) << 4));
dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval);
/* signal optimization parameter */
if (state->fe.dtv_property_cache.isdbt_partial_reception) {
seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
for (i = 1; i < 3; i++)
nbseg_diff +=
(state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
for (i = 0; i < nbseg_diff; i++)
seg_diff_mask |= 1 << permu_seg[i + 1];
} else {
for (i = 0; i < 3; i++)
nbseg_diff +=
(state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
for (i = 0; i < nbseg_diff; i++)
seg_diff_mask |= 1 << permu_seg[i];
}
dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
state->differential_constellation = (seg_diff_mask != 0);
dib8000_set_diversity_in(&state->fe, state->diversity_onoff);
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
seg_mask13 = 0x00E0;
else // 1-segment
seg_mask13 = 0x0040;
} else
seg_mask13 = 0x1fff;
// WRITE: Mode & Diff mask
dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode))
dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
else
dib8000_write_word(state, 268, (2 << 9) | 39); //init value
// ---- SMALL ----
// P_small_seg_diff
dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
dib8000_write_word(state, 353, seg_mask13); // ADDR 353
/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
// dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
// ---- SMALL ----
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
switch (state->fe.dtv_property_cache.transmission_mode) {
case TRANSMISSION_MODE_2K:
if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
ncoeff = coeff_2k_sb_1seg_dqpsk;
else // QPSK or QAM
ncoeff = coeff_2k_sb_1seg;
} else { // 3-segments
if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
else // QPSK or QAM on external segments
ncoeff = coeff_2k_sb_3seg_0dqpsk;
} else { // QPSK or QAM on central segment
if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
ncoeff = coeff_2k_sb_3seg_1dqpsk;
else // QPSK or QAM on external segments
ncoeff = coeff_2k_sb_3seg;
}
}
break;
case TRANSMISSION_MODE_4K:
if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
ncoeff = coeff_4k_sb_1seg_dqpsk;
else // QPSK or QAM
ncoeff = coeff_4k_sb_1seg;
} else { // 3-segments
if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
} else { // QPSK or QAM on external segments
ncoeff = coeff_4k_sb_3seg_0dqpsk;
}
} else { // QPSK or QAM on central segment
if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
ncoeff = coeff_4k_sb_3seg_1dqpsk;
} else // QPSK or QAM on external segments
ncoeff = coeff_4k_sb_3seg;
}
}
break;
case TRANSMISSION_MODE_AUTO:
case TRANSMISSION_MODE_8K:
default:
if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
ncoeff = coeff_8k_sb_1seg_dqpsk;
else // QPSK or QAM
ncoeff = coeff_8k_sb_1seg;
} else { // 3-segments
if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
} else { // QPSK or QAM on external segments
ncoeff = coeff_8k_sb_3seg_0dqpsk;
}
} else { // QPSK or QAM on central segment
if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
ncoeff = coeff_8k_sb_3seg_1dqpsk;
} else // QPSK or QAM on external segments
ncoeff = coeff_8k_sb_3seg;
}
}
break;
}
}
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
for (i = 0; i < 8; i++)
dib8000_write_word(state, 343 + i, ncoeff[i]);
// P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
dib8000_write_word(state, 351,
(state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
// ---- COFF ----
// Carloff, the most robust
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots
// P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
// 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
dib8000_write_word(state, 187,
(4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2)
| 0x3);
/* // P_small_coef_ext_enable = 1 */
/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
// 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)
if (mode == 3)
dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
else
dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
// P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
// P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
// P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
// P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
// P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
dib8000_write_word(state, 181, 300);
dib8000_write_word(state, 182, 150);
dib8000_write_word(state, 183, 80);
dib8000_write_word(state, 184, 300);
dib8000_write_word(state, 185, 150);
dib8000_write_word(state, 186, 80);
} else { // Sound Broadcasting mode 3 seg
// P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
/* if (mode == 3) */
/* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
/* else */
/* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
// P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
// P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
// P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
//P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
// P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
dib8000_write_word(state, 181, 350);
dib8000_write_word(state, 182, 300);
dib8000_write_word(state, 183, 250);
dib8000_write_word(state, 184, 350);
dib8000_write_word(state, 185, 300);
dib8000_write_word(state, 186, 250);
}
} else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
dib8000_write_word(state, 180, (16 << 6) | 9);
dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
coff_pow = 0x2800;
for (i = 0; i < 6; i++)
dib8000_write_word(state, 181 + i, coff_pow);
// P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
// 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
dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
// P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
// P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
}
// ---- FFT ----
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0) // 1-seg
dib8000_write_word(state, 178, 64); // P_fft_powrange=64
else
dib8000_write_word(state, 178, 32); // P_fft_powrange=32
/* make the cpil_coff_lock more robust but slower p_coff_winlen
* 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
*/
/* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
else
dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
//dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
if (!autosearching)
dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
else
dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
/* offset loop parameters */
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
/* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
else // Sound Broadcasting mode 3 seg
/* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
} else
// TODO in 13 seg, timf_alpha can always be the same or not ?
/* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
/* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
else // Sound Broadcasting mode 3 seg
/* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
} else
/* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
/* P_dvsy_sync_wait - reuse mode */
switch (state->fe.dtv_property_cache.transmission_mode) {
case TRANSMISSION_MODE_8K:
mode = 256;
break;
case TRANSMISSION_MODE_4K:
mode = 128;
break;
default:
case TRANSMISSION_MODE_2K:
mode = 64;
break;
}
if (state->cfg.diversity_delay == 0)
mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
else
mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
mode <<= 4;
dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
/* channel estimation fine configuration */
switch (max_constellation) {
case QAM_64:
ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
//if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
break;
case QAM_16:
ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
//if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
break;
default:
ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
break;
}
for (mode = 0; mode < 4; mode++)
dib8000_write_word(state, 215 + mode, coeff[mode]);
// update ana_gain depending on max constellation
dib8000_write_word(state, 116, ana_gain);
// update ADC target depending on ana_gain
if (ana_gain) { // set -16dB ADC target for ana_gain=-1
for (i = 0; i < 10; i++)
dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
} else { // set -22dB ADC target for ana_gain=0
for (i = 0; i < 10; i++)
dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
}
// ---- ANA_FE ----
if (state->fe.dtv_property_cache.isdbt_sb_mode) {
if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
ana_fe = ana_fe_coeff_3seg;
else // 1-segment
ana_fe = ana_fe_coeff_1seg;
} else
ana_fe = ana_fe_coeff_13seg;
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
for (mode = 0; mode < 24; mode++)
dib8000_write_word(state, 117 + mode, ana_fe[mode]);
// ---- CHAN_BLK ----
for (i = 0; i < 13; i++) {
if ((((~seg_diff_mask) >> i) & 1) == 1) {
P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
}
}
dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
// "P_cspu_left_edge" not used => do not care
// "P_cspu_right_edge" not used => do not care
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
if (state->fe.dtv_property_cache.isdbt_partial_reception == 0 // 1-segment
&& state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
//dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
}
} else if (state->isdbt_cfg_loaded == 0) {
dib8000_write_word(state, 228, 0); // default value
dib8000_write_word(state, 265, 31); // default value
dib8000_write_word(state, 205, 0x200f); // init value
}
// ---- TMCC ----
for (i = 0; i < 3; i++)
tmcc_pow +=
(((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count);
// Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
// Threshold is set at 1/4 of max power.
tmcc_pow *= (1 << (9 - 2));
dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
//dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
// ---- PHA3 ----
if (state->isdbt_cfg_loaded == 0)
dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
state->isdbt_cfg_loaded = 0;
else
state->isdbt_cfg_loaded = 1;
}
Generated by GNU enscript 1.6.4.