void frontend_tune_restart(struct dibFrontend *fe, enum restart_tune_process option, struct dibChannel * ch) { struct dibChannelFEInfo *info = channel_frontend_info(ch, fe->id); fe->status = FE_STATUS_TUNE_PENDING; switch(option) { default: case FE_RESTART_TUNE_PROCESS_FROM_TUNER: info->tune_time_locked = info->tune_time_estimation[TUNE_TIME_LOCKED] = ch->context.tune_time_estimation[TUNE_TIME_LOCKED]; info->tune_time_data = info->tune_time_estimation[TUNE_TIME_DATA] = ch->context.tune_time_estimation[TUNE_TIME_DATA]; info->tune_start_time = fe->time_steady = systime(); dbgpl(NULL,"Full restart of fe %d (from TUNER)",fe->id); fe->tune_state = CT_START; if (fe->demod_info) fe->demod_info->callback_time_agc = FE_CALLBACK_TIME_NEVER; if (fe->demod_info) fe->demod_info->callback_time = FE_CALLBACK_TIME_NEVER; #ifdef CHANDEC_SH_FEC if (fe->channel_decoder_info) fe->channel_decoder_info->callback_time = FE_CALLBACK_TIME_NEVER; #endif break; case FE_RESTART_TUNE_PROCESS_FROM_AGC: dbgpl(NULL,"Partial restart of fe %d (from AGC only)",fe->id); if (fe->tune_state > CT_AGC_START) fe->tune_state = CT_AGC_START; if (fe->demod_info) fe->demod_info->callback_time = FE_CALLBACK_TIME_NEVER; #ifdef CHANDEC_SH_FEC if (fe->channel_decoder_info) fe->channel_decoder_info->callback_time = FE_CALLBACK_TIME_NEVER; #endif break; case FE_RESTART_TUNE_PROCESS_FROM_DEMOD: dbgpl(NULL,"Partial restart of fe %d (from DEMOD only)",fe->id); if (fe->tune_state > CT_DEMOD_START) fe->tune_state = CT_DEMOD_START; #ifdef CHANDEC_SH_FEC if (fe->channel_decoder_info) fe->channel_decoder_info->callback_time = FE_CALLBACK_TIME_NEVER; #endif break; case FE_SHUTDOWN: fe->tune_state = CT_SHUTDOWN; break; } }
int dib7000p_reset_gpio(struct dib7000p_state *st) { dbgpl(&dib7000p_dbg, "Reset GPIO"); /* reset the GPIOs */ dbgpl(&dib7000p_dbg, "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos); dib7000p_write_word(st, 1029, st->gpio_dir); dib7000p_write_word(st, 1030, st->gpio_val); /* TODO 1031 is P_gpio_od */ dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos); dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div); return DIB_RETURN_SUCCESS; }
int dib7000p_enable_vbg_voltage(struct dibFrontend *fe) { struct dib7000p_state *state = fe->demod_priv; dbgpl(&dib7000p_dbg, "enabling VBG voltage in the ADC"); /* P_dual_adc_cfg0 */ dib7000p_write_word(state, 908, (state->cfg.enable_current_mirror & 1) << 7); /* P_dual_adc_cfg1 = 3, P_sar_adc_cfg = 2 */ dib7000p_write_word(state, 909, ((state->cfg.disable_sample_and_hold & 1) << 4) | (3 << 2) | (2 << 0)); return 0; }
int dib8000p_enable_vbg_voltage(struct dibFrontend *fe) { struct dib8000p_state *state = fe->demod_priv; dbgpl(&dib8000p_dbg, "enabling VBG voltage in the ADC"); /* P_dual_adc_cfg0 */ dib8000p_write_word(state, 907, 0x0000); /* P_dual_adc_cfg1 = 3, P_sar_adc_cfg = 2 */ dib8000p_write_word(state, 908, (3 << 2) | (2 << 0)); return DIB_RETURN_SUCCESS; }
int dib7000m_enable_vbg_voltage(struct dibFrontend *demod) { struct dib7000m_state *state = demod->demod_priv; dbgpl(&dib7000m_dbg, "enabling VBG voltage in the ADC"); /* P_dual_adc_cfg0 */ dib7000m_write_word(state, 913, 0x0000); /* P_dual_adc_cfg1 = 3, P_sar_adc_cfg = 2 */ dib7000m_write_word(state, 914, (3 << 2) | (2 << 0)); return DIB_RETURN_SUCCESS; }
int dib8000p_cfg_gpio(struct dib8000p_state *st, uint8_t num, uint8_t dir, uint8_t val) { st->cfg.gpio_dir = dib8000p_read_word(st, 1029); st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */ st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */ dib8000p_write_word(st, 1029, st->cfg.gpio_dir); st->cfg.gpio_val = dib8000p_read_word(st, 1030); st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */ st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */ dib8000p_write_word(st, 1030, st->cfg.gpio_val); dbgpl(&dib8000p_dbg, "gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val); return DIB_RETURN_SUCCESS; }
int dib7000m_cfg_gpio(struct dib7000m_state *st, uint8_t num, uint8_t dir, uint8_t val) { st->gpio_dir = dib7000m_read_word(st, 773); st->gpio_dir &= ~(1 << num); /* reset the direction bit */ st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */ dib7000m_write_word(st, 773, st->gpio_dir); st->gpio_val = dib7000m_read_word(st, 774); st->gpio_val &= ~(1 << num); /* reset the direction bit */ st->gpio_val |= (val & 0x01) << num; /* set the new value */ dib7000m_write_word(st, 774, st->gpio_val); dbgpl(&dib7000m_dbg, "gpio dir: %04x: gpio val: %04x", st->gpio_dir, st->gpio_val); return DIB_RETURN_SUCCESS; }
uint16_t frontend_get_isdbt_sb_channels(struct dibFrontend *fe[], uint32_t freq , uint32_t bw, int num, struct dibChannel ch[]) { uint16_t seg_bw_khz = 429; int16_t rf_offset_khz = 0; uint16_t total_segment_number = (uint16_t)((bw / seg_bw_khz) - 1); // 1 is the freq guard int segment_index = 0, channel_index = 0, subch_id = -1; int i; dbgpl(NULL, "will search SB on %d potential segment(s) inside a bandwidth of %dkhz arround FR freq %dkhz", total_segment_number, bw, freq); for (i = 0; i < num; i++) { if (demod_init(fe[i]) != 0) { DibDbgPrint("-E- Tuner init failed\n"); return 0; } if (tuner_init(fe[i]) != 0) { DibDbgPrint("-E- Tuner init failed\n"); return 0; } } for (segment_index = 1; segment_index <= total_segment_number; segment_index++) { int success, fe_fail_count; channel_init(&ch[channel_index], STANDARD_ISDBT); /* compute segment center freq */ rf_offset_khz = seg_bw_khz * (segment_index - (total_segment_number/2) - (total_segment_number%2)); dbgpl(NULL,"rf_offset_khz = %d",rf_offset_khz); /* add a half of seg BW offset is total number of connected seg is even */ if((total_segment_number%2) == 0) { dbgpl(NULL,"compensate for 1/2 seg (%d khz) tune freq because sb_conn_total_seg is even = %d",seg_bw_khz, total_segment_number); rf_offset_khz-=(seg_bw_khz/2); } dbgpl(NULL,"rf_offset_khz = %d",rf_offset_khz); ch[channel_index].RF_kHz = freq + rf_offset_khz; ch[channel_index].bandwidth_kHz = bw; ch[channel_index].u.isdbt.sb_mode = 1; if (subch_id != -1) subch_id += 3; ch[channel_index].u.isdbt.sb_subchannel = subch_id; dbgpl(NULL,"---------------------- Start search on segment #%d center freq = %dkhz (%d+%d, %d)--------------------- ", segment_index,ch[channel_index].RF_kHz, freq, rf_offset_khz, subch_id); for (i = 0; i < num; i++) frontend_tune_restart(fe[i], FE_RESTART_TUNE_PROCESS_FROM_TUNER, &ch[channel_index]); do { success = 0; fe_fail_count = 0; for (i = 0; i < num; i++) { frontend_tune(fe[i], &ch[channel_index]); if (fe[i]->status_has_changed && (frontend_get_status(fe[i]) == FE_STATUS_DEMOD_SUCCESS || frontend_get_status(fe[i]) == FE_STATUS_FFT_SUCCESS)) { //dbgpl(&adapter_dbg, "Autosearch succeeded on FE %d", fe[i]->id); frontend_get_channel(fe[i], &ch[channel_index]); /* we read the channel parameters from the frontend which was successful */ if (ch[channel_index].u.isdbt.partial_reception == 1) { ch[channel_index].bandwidth_kHz = seg_bw_khz * 3; /* bandwidth is for 3 segments */ segment_index++; /* no need to check the next segment */ } else ch[channel_index].bandwidth_kHz = seg_bw_khz; #ifdef DIBCOM_EXTENDED_MONITORING dump_digital_channel_params(&ch[channel_index]); #endif } if (frontend_get_status(fe[i]) == FE_STATUS_LOCKED) { subch_id = ch[channel_index].u.isdbt.sb_subchannel; channel_index++; success = 1; break; } else if(frontend_get_status(fe[i]) == FE_STATUS_TUNE_FAILED) { fe_fail_count++; } } } while (!success && fe_fail_count != num); if (success) DibDbgPrint("-I- Autosearch succeeded for demod %d channel_index = %d - done.\n",i, channel_index); else DibDbgPrint("-I- Autosearch failled for demod %d channel_index = %d - done. %d/%d\n",i, channel_index, fe_fail_count, num); } return channel_index; }