📄 af9005-fe.c
字号:
if (ret) return ret; /* IF TOP */ ret = af9005_read_word_agc(state->d, xd_p_reg_aagc_if_top_numerator_9_8, xd_p_reg_aagc_if_top_numerator_7_0, 0, 2, &state->original_if_top); if (ret) return ret; /* ACI 0 IF TOP */ ret = af9005_read_word_agc(state->d, 0xA60E, 0xA60A, 4, 2, &state->original_aci0_if_top); if (ret) return ret; /* ACI 1 IF TOP */ ret = af9005_read_word_agc(state->d, 0xA60E, 0xA60B, 6, 2, &state->original_aci1_if_top); if (ret) return ret;#if 0 /* (For strong signal) IF minimal value */ /* FIXME not in the captured data, wrong register? */ ret = af9005_read_word_agc(state->d, xd_p_reg_aagc_min_if_agc_9_8, xd_p_reg_aagc_min_if_agc_7_0, 0, 2, &state->original_if_min); if (ret) return ret; /* (For strong signal) IF minimal value */ /* FIXME not in the captured data, wrong register? */ ret = af9005_read_word_agc(state->d, 0xA60E, 0xA608, 0, 2, &state->original_aci0_if_min); if (ret) return ret;#endif /* attach tuner and init */ if (fe->ops.tuner_ops.release == NULL) { /* read tuner and board id from eeprom */ ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2); if (ret) { err("Impossible to read EEPROM\n"); return ret; } deb_info("Tuner id %d, board id %d\n", buf[0], buf[1]); switch (buf[0]) { case 2: /* MT2060 */ /* read if1 from eeprom */ ret = af9005_read_eeprom(adap->dev, 0xc8, buf, 2); if (ret) { err("Impossible to read EEPROM\n"); return ret; } if1 = (u16) (buf[0] << 8) + buf[1]; if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, &af9005_mt2060_config, if1) == NULL) { deb_info("MT2060 attach failed\n"); return -ENODEV; } break; case 3: /* QT1010 */ case 9: /* QT1010B */ if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, &af9005_qt1010_config) ==NULL) { deb_info("QT1010 attach failed\n"); return -ENODEV; } break; default: err("Unsupported tuner type %d", buf[0]); return -ENODEV; } ret = fe->ops.tuner_ops.init(fe); if (ret) return ret; } deb_info("profit!\n"); return 0;}static int af9005_fe_sleep(struct dvb_frontend *fe){ return af9005_fe_power(fe, 0);}static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire){ struct af9005_fe_state *state = fe->demodulator_priv; if (acquire) { state->opened++; } else { state->opened--; if (!state->opened) af9005_led_control(state->d, 0); } return 0;}static int af9005_fe_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep){ struct af9005_fe_state *state = fe->demodulator_priv; int ret; u8 temp, temp0, temp1, temp2; deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency, fep->u.ofdm.bandwidth); if (fe->ops.tuner_ops.release == NULL) { err("Tuner not attached"); return -ENODEV; } deb_info("turn off led\n"); /* not in the log */ ret = af9005_led_control(state->d, 0); if (ret) return ret; /* not sure about the bits */ ret = af9005_write_register_bits(state->d, XD_MP2IF_MISC, 2, 1, 0); if (ret) return ret; /* set FCW to default value */ deb_info("set FCW to default value\n"); temp0 = (u8) (state->original_fcw & 0x000000ff); temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8); temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16); ret = af9005_write_ofdm_register(state->d, 0xae1a, temp0); if (ret) return ret; ret = af9005_write_ofdm_register(state->d, 0xae19, temp1); if (ret) return ret; ret = af9005_write_ofdm_register(state->d, 0xae18, temp2); if (ret) return ret; /* restore original TOPs */ deb_info("restore original TOPs\n"); ret = af9005_write_word_agc(state->d, xd_p_reg_aagc_rf_top_numerator_9_8, xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2, state->original_rf_top); if (ret) return ret; ret = af9005_write_word_agc(state->d, xd_p_reg_aagc_if_top_numerator_9_8, xd_p_reg_aagc_if_top_numerator_7_0, 0, 2, state->original_if_top); if (ret) return ret; ret = af9005_write_word_agc(state->d, 0xA60E, 0xA60A, 4, 2, state->original_aci0_if_top); if (ret) return ret; ret = af9005_write_word_agc(state->d, 0xA60E, 0xA60B, 6, 2, state->original_aci1_if_top); if (ret) return ret; /* select bandwith */ deb_info("select bandwidth"); ret = af9005_fe_select_bw(state->d, fep->u.ofdm.bandwidth); if (ret) return ret; ret = af9005_fe_program_cfoe(state->d, fep->u.ofdm.bandwidth); if (ret) return ret; /* clear easy mode flag */ deb_info("clear easy mode flag\n"); ret = af9005_write_ofdm_register(state->d, 0xaefd, 0); if (ret) return ret; /* set unplug threshold to original value */ deb_info("set unplug threshold to original value\n"); ret = af9005_write_ofdm_register(state->d, xd_p_reg_unplug_th, state->original_if_unplug_th); if (ret) return ret;#if 0 ret = af9005_write_ofdm_register(state->d, xd_p_reg_unplug_rf_gain_th, state->original_rf_unplug_th); if (ret) return ret;#endif /* set tuner */ deb_info("set tuner\n"); ret = fe->ops.tuner_ops.set_params(fe, fep); if (ret) return ret; /* trigger ofsm */ deb_info("trigger ofsm\n"); temp = 0; ret = af9005_write_tuner_registers(state->d, 0xffff, &temp, 1); if (ret) return ret; /* clear retrain and freeze flag */ deb_info("clear retrain and freeze flag\n"); ret = af9005_write_register_bits(state->d, xd_p_reg_api_retrain_request, reg_api_retrain_request_pos, 2, 0); if (ret) return ret;#if 0 /* FIXME not found in captured data */ /* clear tpsrdy */ deb_info("clear tpsrdy\n"); ret = af9005_write_register_bits(state->d, xd_p_reg_dca_api_tpsrdy, reg_dca_api_tpsrdy_pos, reg_dca_api_tpsrdy_len, 0); if (ret) return ret; /* clear dca_en */ deb_info("clear dca_en\n"); ret = af9005_write_register_bits(state->d, xd_p_reg_dca_en, reg_dca_en_pos, reg_dca_en_len, 0); if (ret) return ret; /* clear MP2IF lock */ deb_info("clear MP2IF lock\n"); ret = af9005_write_register_bits(state->d, xd_r_mp2if_sync_byte_locked, mp2if_sync_byte_locked_pos, mp2if_sync_byte_locked_len, 0); if (ret) return ret; /* clear TPS lock flag */ deb_info("clear TPS lock flag\n"); ret = af9005_write_register_bits(state->d, xd_p_fd_tpsd_lock, fd_tpsd_lock_pos, fd_tpsd_lock_len, 1); if (ret) return ret; /* write TPS information to demods here for easy mode */ /* FIXME in the sample code but not in captured data, so I didn't bother to write the code */#endif /* reset pre viterbi and post viterbi registers and statistics */ af9005_reset_pre_viterbi(fe); af9005_reset_post_viterbi(fe); state->pre_vit_error_count = 0; state->pre_vit_bit_count = 0; state->ber = 0; state->post_vit_error_count = 0; /* state->unc = 0; commented out since it should be ever increasing */ state->abort_count = 0; state->next_status_check = jiffies; state->strong = -1; return 0;}static int af9005_fe_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep){ struct af9005_fe_state *state = fe->demodulator_priv; int ret; u8 temp; /* mode */ ret = af9005_read_register_bits(state->d, xd_g_reg_tpsd_const, reg_tpsd_const_pos, reg_tpsd_const_len, &temp); if (ret) return ret; deb_info("===== fe_get_frontend ==============\n"); deb_info("CONSTELLATION "); switch (temp) { case 0: fep->u.ofdm.constellation = QPSK; deb_info("QPSK\n"); break; case 1: fep->u.ofdm.constellation = QAM_16; deb_info("QAM_16\n"); break; case 2: fep->u.ofdm.constellation = QAM_64; deb_info("QAM_64\n"); break; } /* tps hierarchy and alpha value */ ret = af9005_read_register_bits(state->d, xd_g_reg_tpsd_hier, reg_tpsd_hier_pos, reg_tpsd_hier_len, &temp); if (ret) return ret; deb_info("HIERARCHY "); switch (temp) { case 0: fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; deb_info("NONE\n"); break; case 1: fep->u.ofdm.hierarchy_information = HIERARCHY_1; deb_info("1\n"); break; case 2: fep->u.ofdm.hierarchy_information = HIERARCHY_2; deb_info("2\n"); break; case 3: fep->u.ofdm.hierarchy_information = HIERARCHY_4; deb_info("4\n"); break; } /* high/low priority */ ret = af9005_read_register_bits(state->d, xd_g_reg_dec_pri, reg_dec_pri_pos, reg_dec_pri_len, &temp); if (ret) return ret; /* if temp is set = high priority */ deb_info("PRIORITY %s\n", temp ? "high" : "low"); /* high coderate */ ret = af9005_read_register_bits(state->d, xd_g_reg_tpsd_hpcr, reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len, &temp); if (ret) return ret; deb_info("CODERATE HP "); switch (temp) { case 0: fep->u.ofdm.code_rate_HP = FEC_1_2; deb_info("FEC_1_2\n"); break; case 1: fep->u.ofdm.code_rate_HP = FEC_2_3; deb_info("FEC_2_3\n"); break; case 2: fep->u.ofdm.code_rate_HP = FEC_3_4; deb_info("FEC_3_4\n"); break; case 3: fep->u.ofdm.code_rate_HP = FEC_5_6; deb_info("FEC_5_6\n"); break; case 4: fep->u.ofdm.code_rate_HP = FEC_7_8; deb_info("FEC_7_8\n"); break; } /* low coderate */ ret = af9005_read_register_bits(state->d, xd_g_reg_tpsd_lpcr, reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len, &temp); if (ret) return ret; deb_info("CODERATE LP "); switch (temp) { case 0: fep->u.ofdm.code_rate_LP = FEC_1_2; deb_info("FEC_1_2\n"); break; case 1: fep->u.ofdm.code_rate_LP = FEC_2_3; deb_info("FEC_2_3\n"); break; case 2: fep->u.ofdm.code_rate_LP = FEC_3_4; deb_info("FEC_3_4\n"); break; case 3: fep->u.ofdm.code_rate_LP = FEC_5_6; deb_info("FEC_5_6\n"); break; case 4: fep->u.ofdm.code_rate_LP = FEC_7_8; deb_info("FEC_7_8\n"); break; } /* guard interval */ ret = af9005_read_register_bits(state->d, xd_g_reg_tpsd_gi, reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp); if (ret) return ret; deb_info("GUARD INTERVAL "); switch (temp) { case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; deb_info("1_32\n"); break; case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; deb_info("1_16\n"); break; case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; deb_info("1_8\n"); break; case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; deb_info("1_4\n"); break; } /* fft */ ret = af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod, reg_tpsd_txmod_pos, reg_tpsd_txmod_len, &temp); if (ret) return ret; deb_info("TRANSMISSION MODE "); switch (temp) { case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; deb_info("2K\n"); break; case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; deb_info("8K\n"); break; } /* bandwidth */ ret = af9005_read_register_bits(state->d, xd_g_reg_bw, reg_bw_pos, reg_bw_len, &temp); deb_info("BANDWIDTH "); switch (temp) { case 0: fep->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; deb_info("6\n"); break; case 1: fep->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; deb_info("7\n"); break; case 2: fep->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; deb_info("8\n"); break; } return 0;}static void af9005_fe_release(struct dvb_frontend *fe){ struct af9005_fe_state *state = (struct af9005_fe_state *)fe->demodulator_priv; kfree(state);}static struct dvb_frontend_ops af9005_fe_ops;struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d){ struct af9005_fe_state *state = NULL; /* allocate memory for the internal state */ state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL); if (state == NULL) goto error; deb_info("attaching frontend af9005\n"); state->d = d; state->opened = 0; memcpy(&state->frontend.ops, &af9005_fe_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; return &state->frontend; error: return NULL;}static struct dvb_frontend_ops af9005_fe_ops = { .info = { .name = "AF9005 USB DVB-T", .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 250000, .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO, }, .release = af9005_fe_release, .init = af9005_fe_init, .sleep = af9005_fe_sleep, .ts_bus_ctrl = af9005_ts_bus_ctrl, .set_frontend = af9005_fe_set_frontend, .get_frontend = af9005_fe_get_frontend, .read_status = af9005_fe_read_status, .read_ber = af9005_fe_read_ber, .read_signal_strength = af9005_fe_read_signal_strength, .read_snr = af9005_fe_read_snr, .read_ucblocks = af9005_fe_read_unc_blocks,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -