Lines Matching +full:nco +full:- +full:ref
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
18 MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
54 /* ------------------------------------------------------------------------ */
106 .addr = state->cfg->i2c_addr, .flags = 0, in lgdt3305_write_reg()
112 ret = i2c_transfer(state->i2c_adap, &msg, 1); in lgdt3305_write_reg()
115 lg_err("error (addr %02x %02x <- %02x, err = %i)\n", in lgdt3305_write_reg()
120 return -EREMOTEIO; in lgdt3305_write_reg()
130 { .addr = state->cfg->i2c_addr, in lgdt3305_read_reg()
132 { .addr = state->cfg->i2c_addr, in lgdt3305_read_reg()
138 ret = i2c_transfer(state->i2c_adap, msg, 2); in lgdt3305_read_reg()
142 state->cfg->i2c_addr, reg, ret); in lgdt3305_read_reg()
146 return -EREMOTEIO; in lgdt3305_read_reg()
192 for (i = 0; i < len - 1; i++) { in lgdt3305_write_regs()
200 /* ------------------------------------------------------------------------ */
229 enum lgdt3305_tp_clock_edge edge = state->cfg->tpclk_edge; in lgdt3305_mpeg_mode_polarity()
230 enum lgdt3305_tp_clock_mode mode = state->cfg->tpclk_mode; in lgdt3305_mpeg_mode_polarity()
231 enum lgdt3305_tp_valid_polarity valid = state->cfg->tpvalid_polarity; in lgdt3305_mpeg_mode_polarity()
271 switch (p->modulation) { in lgdt3305_set_modulation()
282 return -EINVAL; in lgdt3305_set_modulation()
294 switch (p->modulation) { in lgdt3305_set_filter_extension()
303 return -EINVAL; in lgdt3305_set_filter_extension()
310 /* ------------------------------------------------------------------------ */
317 switch (p->modulation) { in lgdt3305_passband_digital_agc()
328 return -EINVAL; in lgdt3305_passband_digital_agc()
331 lg_dbg("agc ref: 0x%04x\n", agc_ref); in lgdt3305_passband_digital_agc()
344 switch (p->modulation) { in lgdt3305_rfagc_loop()
355 * DT3304 and re-write this switch..case block */ in lgdt3305_rfagc_loop()
356 if (state->cfg->demod_chip == LGDT3304) in lgdt3305_rfagc_loop()
358 else /* (state->cfg->demod_chip == LGDT3305) */ in lgdt3305_rfagc_loop()
362 return -EINVAL; in lgdt3305_rfagc_loop()
365 if (state->cfg->rf_agc_loop) { in lgdt3305_rfagc_loop()
394 switch (p->modulation) { in lgdt3305_agc_setup()
405 return -EINVAL; in lgdt3305_agc_setup()
411 switch (state->cfg->demod_chip) { in lgdt3305_agc_setup()
421 return -EINVAL; in lgdt3305_agc_setup()
432 switch (p->modulation) { in lgdt3305_set_agc_power_ref()
434 if (state->cfg->usref_8vsb) in lgdt3305_set_agc_power_ref()
435 usref = state->cfg->usref_8vsb; in lgdt3305_set_agc_power_ref()
438 if (state->cfg->usref_qam64) in lgdt3305_set_agc_power_ref()
439 usref = state->cfg->usref_qam64; in lgdt3305_set_agc_power_ref()
442 if (state->cfg->usref_qam256) in lgdt3305_set_agc_power_ref()
443 usref = state->cfg->usref_qam256; in lgdt3305_set_agc_power_ref()
446 return -EINVAL; in lgdt3305_set_agc_power_ref()
462 /* ------------------------------------------------------------------------ */
472 switch (p->modulation) { in lgdt3305_spectral_inversion()
483 ret = -EINVAL; in lgdt3305_spectral_inversion()
493 u64 nco; in lgdt3305_set_if() local
495 switch (p->modulation) { in lgdt3305_set_if()
497 if_freq_khz = state->cfg->vsb_if_khz; in lgdt3305_set_if()
501 if_freq_khz = state->cfg->qam_if_khz; in lgdt3305_set_if()
504 return -EINVAL; in lgdt3305_set_if()
507 nco = if_freq_khz / 10; in lgdt3305_set_if()
509 switch (p->modulation) { in lgdt3305_set_if()
511 nco <<= 24; in lgdt3305_set_if()
512 do_div(nco, 625); in lgdt3305_set_if()
516 nco <<= 28; in lgdt3305_set_if()
517 do_div(nco, 625); in lgdt3305_set_if()
520 return -EINVAL; in lgdt3305_set_if()
523 nco1 = (nco >> 24) & 0x3f; in lgdt3305_set_if()
525 nco2 = (nco >> 16) & 0xff; in lgdt3305_set_if()
526 nco3 = (nco >> 8) & 0xff; in lgdt3305_set_if()
527 nco4 = nco & 0xff; in lgdt3305_set_if()
534 lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n", in lgdt3305_set_if()
540 /* ------------------------------------------------------------------------ */
544 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3305_i2c_gate_ctrl()
546 if (state->cfg->deny_i2c_rptr) in lgdt3305_i2c_gate_ctrl()
557 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3305_sleep()
567 /* tristate the IF-AGC pin */ in lgdt3305_sleep()
569 /* tristate the RF-AGC pin */ in lgdt3305_sleep()
585 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3305_init()
649 switch (state->cfg->demod_chip) { in lgdt3305_init()
659 ret = -EINVAL; in lgdt3305_init()
671 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt3304_set_parameters()
672 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3304_set_parameters()
675 lg_dbg("(%d, %d)\n", p->frequency, p->modulation); in lgdt3304_set_parameters()
677 if (fe->ops.tuner_ops.set_params) { in lgdt3304_set_parameters()
678 ret = fe->ops.tuner_ops.set_params(fe); in lgdt3304_set_parameters()
679 if (fe->ops.i2c_gate_ctrl) in lgdt3304_set_parameters()
680 fe->ops.i2c_gate_ctrl(fe, 0); in lgdt3304_set_parameters()
683 state->current_frequency = p->frequency; in lgdt3304_set_parameters()
698 /* reg 0x030d is 3304-only... seen in vsb and qam usbsnoops... */ in lgdt3304_set_parameters()
699 switch (p->modulation) { in lgdt3304_set_parameters()
715 return -EINVAL; in lgdt3304_set_parameters()
720 state->cfg->spectral_inversion in lgdt3304_set_parameters()
725 state->current_modulation = p->modulation; in lgdt3304_set_parameters()
727 ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode); in lgdt3304_set_parameters()
739 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt3305_set_parameters()
740 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3305_set_parameters()
743 lg_dbg("(%d, %d)\n", p->frequency, p->modulation); in lgdt3305_set_parameters()
745 if (fe->ops.tuner_ops.set_params) { in lgdt3305_set_parameters()
746 ret = fe->ops.tuner_ops.set_params(fe); in lgdt3305_set_parameters()
747 if (fe->ops.i2c_gate_ctrl) in lgdt3305_set_parameters()
748 fe->ops.i2c_gate_ctrl(fe, 0); in lgdt3305_set_parameters()
751 state->current_frequency = p->frequency; in lgdt3305_set_parameters()
780 state->cfg->spectral_inversion in lgdt3305_set_parameters()
789 state->current_modulation = p->modulation; in lgdt3305_set_parameters()
791 ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode); in lgdt3305_set_parameters()
804 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3305_get_frontend()
808 p->modulation = state->current_modulation; in lgdt3305_get_frontend()
809 p->frequency = state->current_frequency; in lgdt3305_get_frontend()
813 /* ------------------------------------------------------------------------ */
828 switch (state->current_modulation) { in lgdt3305_read_cr_lock_status()
848 cr_lock_state = "CLOCKQAM-INVALID!"; in lgdt3305_read_cr_lock_status()
859 ret = -EINVAL; in lgdt3305_read_cr_lock_status()
874 switch (state->current_modulation) { in lgdt3305_read_fec_lock_status()
895 ret = -EINVAL; in lgdt3305_read_fec_lock_status()
903 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3305_read_status()
940 switch (state->current_modulation) { in lgdt3305_read_status()
944 if (((LGDT3304 == state->cfg->demod_chip)) && (cr_lock)) in lgdt3305_read_status()
959 ret = -EINVAL; in lgdt3305_read_status()
965 /* ------------------------------------------------------------------------ */
980 return 10*(c - mse); in calculate_snr()
985 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3305_read_snr()
987 u32 c; /* per-modulation SNR calculation constant */ in lgdt3305_read_snr()
989 switch (state->current_modulation) { in lgdt3305_read_snr()
992 /* Use Phase Tracker Mean-Square Error Register */ in lgdt3305_read_snr()
993 /* SNR for ranges from -13.11 to +44.08 */ in lgdt3305_read_snr()
999 /* Use Equalizer Mean-Square Error Register */ in lgdt3305_read_snr()
1000 /* SNR for ranges from -16.12 to +44.08 */ in lgdt3305_read_snr()
1012 c = (state->current_modulation == QAM_64) ? in lgdt3305_read_snr()
1017 return -EINVAL; in lgdt3305_read_snr()
1019 state->snr = calculate_snr(noise, c); in lgdt3305_read_snr()
1021 *snr = (state->snr / ((1 << 24) / 10)); in lgdt3305_read_snr()
1023 state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16); in lgdt3305_read_snr()
1038 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3305_read_signal_strength()
1044 ret = fe->ops.read_snr(fe, &snr); in lgdt3305_read_signal_strength()
1047 /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ in lgdt3305_read_signal_strength()
1048 /* scale the range 0 - 35*2^24 into 0 - 65535 */ in lgdt3305_read_signal_strength()
1049 if (state->snr >= 8960 * 0x10000) in lgdt3305_read_signal_strength()
1052 *strength = state->snr / 8960; in lgdt3305_read_signal_strength()
1057 /* ------------------------------------------------------------------------ */
1067 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3305_read_ucblocks()
1080 fe_tune_settings->min_delay_ms = 500; in lgdt3305_get_tune_settings()
1087 struct lgdt3305_state *state = fe->demodulator_priv; in lgdt3305_release()
1102 lg_dbg("(%d-%04x)\n", in lgdt3305_attach()
1104 config ? config->i2c_addr : 0); in lgdt3305_attach()
1110 state->cfg = config; in lgdt3305_attach()
1111 state->i2c_adap = i2c_adap; in lgdt3305_attach()
1113 switch (config->demod_chip) { in lgdt3305_attach()
1115 memcpy(&state->frontend.ops, &lgdt3304_ops, in lgdt3305_attach()
1119 memcpy(&state->frontend.ops, &lgdt3305_ops, in lgdt3305_attach()
1125 state->frontend.demodulator_priv = state; in lgdt3305_attach()
1141 state->current_frequency = -1; in lgdt3305_attach()
1142 state->current_modulation = -1; in lgdt3305_attach()
1144 return &state->frontend; in lgdt3305_attach()
1147 config->demod_chip ? "LGDT3304" : "LGDT3305"); in lgdt3305_attach()
1199 MODULE_DESCRIPTION("LG Electronics LGDT3304/5 ATSC/QAM-B Demodulator Driver");