📄 af9013.c
字号:
case HIERARCHY_NONE: break; case HIERARCHY_1: buf[0] |= (1 << 4); break; case HIERARCHY_2: buf[0] |= (2 << 4); break; case HIERARCHY_4: buf[0] |= (3 << 4); break; default: return -EINVAL; }; switch (params->constellation) { case QAM_AUTO: *auto_mode = 1; case QPSK: break; case QAM_16: buf[1] |= (1 << 6); break; case QAM_64: buf[1] |= (2 << 6); break; default: return -EINVAL; } /* Use HP. How and which case we can switch to LP? */ buf[1] |= (1 << 4); switch (params->code_rate_HP) { case FEC_AUTO: *auto_mode = 1; case FEC_1_2: break; case FEC_2_3: buf[2] |= (1 << 0); break; case FEC_3_4: buf[2] |= (2 << 0); break; case FEC_5_6: buf[2] |= (3 << 0); break; case FEC_7_8: buf[2] |= (4 << 0); break; default: return -EINVAL; } switch (params->code_rate_LP) { case FEC_AUTO: /* if HIERARCHY_NONE and FEC_NONE then LP FEC is set to FEC_AUTO by dvb_frontend.c for compatibility */ if (params->hierarchy_information != HIERARCHY_NONE) *auto_mode = 1; case FEC_1_2: break; case FEC_2_3: buf[2] |= (1 << 3); break; case FEC_3_4: buf[2] |= (2 << 3); break; case FEC_5_6: buf[2] |= (3 << 3); break; case FEC_7_8: buf[2] |= (4 << 3); break; case FEC_NONE: if (params->hierarchy_information == HIERARCHY_AUTO) break; default: return -EINVAL; } switch (params->bandwidth) { case BANDWIDTH_6_MHZ: break; case BANDWIDTH_7_MHZ: buf[1] |= (1 << 2); break; case BANDWIDTH_8_MHZ: buf[1] |= (2 << 2); break; default: return -EINVAL; } /* program */ for (i = 0; i < sizeof(buf); i++) { ret = af9013_write_reg(state, 0xd3c0 + i, buf[i]); if (ret) break; } return ret;}static int af9013_reset(struct af9013_state *state, u8 sleep){ int ret; u8 tmp, i; deb_info("%s\n", __func__); /* enable OFDM reset */ ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 1); if (ret) goto error; /* start reset mechanism */ ret = af9013_write_reg(state, 0xaeff, 1); if (ret) goto error; /* reset is done when bit 1 is set */ for (i = 0; i < 150; i++) { ret = af9013_read_reg_bits(state, 0xd417, 1, 1, &tmp); if (ret) goto error; if (tmp) break; /* reset done */ msleep(10); } if (!tmp) return -ETIMEDOUT; /* don't clear reset when going to sleep */ if (!sleep) { /* clear OFDM reset */ ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); if (ret) goto error; /* disable OFDM reset */ ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); }error: return ret;}static int af9013_power_ctrl(struct af9013_state *state, u8 onoff){ int ret; deb_info("%s: onoff:%d\n", __func__, onoff); if (onoff) { /* power on */ ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 0); if (ret) goto error; ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); if (ret) goto error; ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); } else { /* power off */ ret = af9013_reset(state, 1); if (ret) goto error; ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 1); }error: return ret;}static int af9013_lock_led(struct af9013_state *state, u8 onoff){ deb_info("%s: onoff:%d\n", __func__, onoff); return af9013_write_reg_bits(state, 0xd730, 0, 1, onoff);}static int af9013_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *params){ struct af9013_state *state = fe->demodulator_priv; int ret; u8 auto_mode; /* auto set TPS */ deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency, params->u.ofdm.bandwidth); state->frequency = params->frequency; /* program CFOE coefficients */ ret = af9013_set_coeff(state, params->u.ofdm.bandwidth); if (ret) goto error; /* program frequency control */ ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth); if (ret) goto error; /* clear TPS lock flag (inverted flag) */ ret = af9013_write_reg_bits(state, 0xd330, 3, 1, 1); if (ret) goto error; /* clear MPEG2 lock flag */ ret = af9013_write_reg_bits(state, 0xd507, 6, 1, 0); if (ret) goto error; /* empty channel function */ ret = af9013_write_reg_bits(state, 0x9bfe, 0, 1, 0); if (ret) goto error; /* empty DVB-T channel function */ ret = af9013_write_reg_bits(state, 0x9bc2, 0, 1, 0); if (ret) goto error; /* program tuner */ if (fe->ops.tuner_ops.set_params) fe->ops.tuner_ops.set_params(fe, params); /* program TPS and bandwidth, check if auto mode needed */ ret = af9013_set_ofdm_params(state, ¶ms->u.ofdm, &auto_mode); if (ret) goto error; if (auto_mode) { /* clear easy mode flag */ ret = af9013_write_reg(state, 0xaefd, 0); deb_info("%s: auto TPS\n", __func__); } else { /* set easy mode flag */ ret = af9013_write_reg(state, 0xaefd, 1); if (ret) goto error; ret = af9013_write_reg(state, 0xaefe, 0); deb_info("%s: manual TPS\n", __func__); } if (ret) goto error; /* everything is set, lets try to receive channel - OFSM GO! */ ret = af9013_write_reg(state, 0xffff, 0); if (ret) goto error;error: return ret;}static int af9013_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p){ struct af9013_state *state = fe->demodulator_priv; int ret; u8 i, buf[3]; deb_info("%s\n", __func__); /* read TPS registers */ for (i = 0; i < 3; i++) { ret = af9013_read_reg(state, 0xd3c0 + i, &buf[i]); if (ret) goto error; } switch ((buf[1] >> 6) & 3) { case 0: p->u.ofdm.constellation = QPSK; break; case 1: p->u.ofdm.constellation = QAM_16; break; case 2: p->u.ofdm.constellation = QAM_64; break; } switch ((buf[0] >> 0) & 3) { case 0: p->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; case 1: p->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; } switch ((buf[0] >> 2) & 3) { case 0: p->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; case 1: p->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; case 2: p->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; case 3: p->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; } switch ((buf[0] >> 4) & 7) { case 0: p->u.ofdm.hierarchy_information = HIERARCHY_NONE; break; case 1: p->u.ofdm.hierarchy_information = HIERARCHY_1; break; case 2: p->u.ofdm.hierarchy_information = HIERARCHY_2; break; case 3: p->u.ofdm.hierarchy_information = HIERARCHY_4; break; } switch ((buf[2] >> 0) & 7) { case 0: p->u.ofdm.code_rate_HP = FEC_1_2; break; case 1: p->u.ofdm.code_rate_HP = FEC_2_3; break; case 2: p->u.ofdm.code_rate_HP = FEC_3_4; break; case 3: p->u.ofdm.code_rate_HP = FEC_5_6; break; case 4: p->u.ofdm.code_rate_HP = FEC_7_8; break; } switch ((buf[2] >> 3) & 7) { case 0: p->u.ofdm.code_rate_LP = FEC_1_2; break; case 1: p->u.ofdm.code_rate_LP = FEC_2_3; break; case 2: p->u.ofdm.code_rate_LP = FEC_3_4; break; case 3: p->u.ofdm.code_rate_LP = FEC_5_6; break; case 4: p->u.ofdm.code_rate_LP = FEC_7_8; break; } switch ((buf[1] >> 2) & 3) { case 0: p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; break; case 1: p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; break; case 2: p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; break; } p->inversion = INVERSION_AUTO; p->frequency = state->frequency;error: return ret;}static int af9013_update_ber_unc(struct dvb_frontend *fe){ struct af9013_state *state = fe->demodulator_priv; int ret; u8 buf[3], i; u32 error_bit_count = 0; u32 total_bit_count = 0; u32 abort_packet_count = 0; state->ber = 0; /* check if error bit count is ready */ ret = af9013_read_reg_bits(state, 0xd391, 4, 1, &buf[0]); if (ret) goto error; if (!buf[0]) goto exit; /* get RSD packet abort count */ for (i = 0; i < 2; i++) { ret = af9013_read_reg(state, 0xd38a + i, &buf[i]); if (ret) goto error; } abort_packet_count = (buf[1] << 8) + buf[0]; /* get error bit count */ for (i = 0; i < 3; i++) { ret = af9013_read_reg(state, 0xd387 + i, &buf[i]); if (ret) goto error; } error_bit_count = (buf[2] << 16) + (buf[1] << 8) + buf[0]; error_bit_count = error_bit_count - abort_packet_count * 8 * 8; /* get used RSD counting period (10000 RSD packets used) */ for (i = 0; i < 2; i++) { ret = af9013_read_reg(state, 0xd385 + i, &buf[i]); if (ret) goto error; } total_bit_count = (buf[1] << 8) + buf[0]; total_bit_count = total_bit_count - abort_packet_count; total_bit_count = total_bit_count * 204 * 8; if (total_bit_count) state->ber = error_bit_count * 1000000000 / total_bit_count; state->ucblocks += abort_packet_count; deb_info("%s: err bits:%d total bits:%d abort count:%d\n", __func__, error_bit_count, total_bit_count, abort_packet_count); /* set BER counting range */ ret = af9013_write_reg(state, 0xd385, 10000 & 0xff); if (ret) goto error; ret = af9013_write_reg(state, 0xd386, 10000 >> 8); if (ret) goto error; /* reset and start BER counter */ ret = af9013_write_reg_bits(state, 0xd391, 4, 1, 1); if (ret) goto error;exit:error: return ret;}static int af9013_update_snr(struct dvb_frontend *fe){ struct af9013_state *state = fe->demodulator_priv; int ret; u8 buf[3], i, len; u32 quant = 0; struct snr_table *snr_table; /* check if quantizer ready (for snr) */ ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]); if (ret) goto error; if (buf[0]) { /* quantizer ready - read it */ for (i = 0; i < 3; i++) { ret = af9013_read_reg(state, 0xd2e3 + i, &buf[i]); if (ret) goto error; } quant = (buf[2] << 16) + (buf[1] << 8) + buf[0]; /* read current constellation */ ret = af9013_read_reg(state, 0xd3c1, &buf[0]); if (ret) goto error; switch ((buf[0] >> 6) & 3) { case 0: len = ARRAY_SIZE(qpsk_snr_table); snr_table = qpsk_snr_table; break; case 1: len = ARRAY_SIZE(qam16_snr_table); snr_table = qam16_snr_table; break; case 2: len = ARRAY_SIZE(qam64_snr_table); snr_table = qam64_snr_table; break; default: len = 0; break; } if (len) { for (i = 0; i < len; i++) { if (quant < snr_table[i].val) { state->snr = snr_table[i].snr * 10; break; } } } /* set quantizer super frame count */ ret = af9013_write_reg(state, 0xd2e2, 1); if (ret) goto error; /* check quantizer availability */ for (i = 0; i < 10; i++) { msleep(10); ret = af9013_read_reg_bits(state, 0xd2e6, 0, 1, &buf[0]); if (ret) goto error; if (!buf[0]) break; } /* reset quantizer */ ret = af9013_write_reg_bits(state, 0xd2e1, 3, 1, 1); if (ret) goto error; }error: return ret;}static int af9013_update_signal_strength(struct dvb_frontend *fe){ struct af9013_state *state = fe->demodulator_priv; int ret; u8 tmp0; u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80; int signal_strength; deb_info("%s\n", __func__); state->signal_strength = 0; ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0); if (ret) goto error; if (tmp0) { ret = af9013_read_reg(state, 0x9bbd, &rf_50); if (ret) goto error; ret = af9013_read_reg(state, 0x9bd0, &rf_80); if (ret) goto error; ret = af9013_read_reg(state, 0x9be2, &if_50); if (ret) goto error; ret = af9013_read_reg(state, 0x9be4, &if_80); if (ret) goto error; ret = af9013_read_reg(state, 0xd07c, &rf_gain); if (ret) goto error; ret = af9013_read_reg(state, 0xd07d, &if_gain); if (ret) goto error; signal_strength = (0xffff / (9 * (rf_50 + if_50) - \ 11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \ 11 * (rf_80 + if_80)); if (signal_strength < 0) signal_strength = 0; else if (signal_strength > 0xffff)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -