Lines Matching +full:re +full:- +full:sampling

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Support for LGDT3306A - 8VSB/QAM-B
6 * - driver structure based on lgdt3305.[ch] by Michael Krufky
7 * - code based on LG3306_V0.35 API by LG Electronics Inc.
17 #include <linux/i2c-mux.h>
22 MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
37 #define DBG_DUMP 4 /* FGR - comment out to remove dump code */
80 * 0000 -> 00FF Common control and status
81 * 1000 -> 10FF Synchronizer control and status
82 * 1F00 -> 1FFF Smart Antenna control and status
83 * 2100 -> 21FF VSB Equalizer control and status
84 * 2800 -> 28FF QAM Equalizer control and status
85 * 3000 -> 30FF FEC control and status
128 .addr = state->cfg->i2c_addr, .flags = 0, in lgdt3306a_write_reg()
134 ret = i2c_transfer(state->i2c_adap, &msg, 1); in lgdt3306a_write_reg()
137 pr_err("error (addr %02x %02x <- %02x, err = %i)\n", in lgdt3306a_write_reg()
142 return -EREMOTEIO; in lgdt3306a_write_reg()
152 { .addr = state->cfg->i2c_addr, in lgdt3306a_read_reg()
154 { .addr = state->cfg->i2c_addr, in lgdt3306a_read_reg()
158 ret = i2c_transfer(state->i2c_adap, msg, 2); in lgdt3306a_read_reg()
162 state->cfg->i2c_addr, reg, ret); in lgdt3306a_read_reg()
166 return -EREMOTEIO; in lgdt3306a_read_reg()
203 /* ------------------------------------------------------------------------ */
230 /* transport packet format - TPSENB=0x80 */ in lgdt3306a_mpeg_mode()
335 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_ts_bus_ctrl()
416 /* 4. ADC sampling frequency rate(2x sampling) */ in lgdt3306a_set_vsb()
424 /* FGR - disable any AICC filtering, testing only */ in lgdt3306a_set_vsb()
430 /* AICCFIXFREQ0 NT N-1(Video rejection) */ in lgdt3306a_set_vsb()
435 /* AICCFIXFREQ1 NT N-1(Audio rejection) */ in lgdt3306a_set_vsb()
440 /* AICCFIXFREQ2 NT Co-Channel(Video rejection) */ in lgdt3306a_set_vsb()
445 /* AICCFIXFREQ3 NT Co-Channel(Audio rejection) */ in lgdt3306a_set_vsb()
451 /* FGR - this works well for HVR-1955,1975 */ in lgdt3306a_set_vsb()
453 /* 5. AICCOPMODE NT N-1 Adj. */ in lgdt3306a_set_vsb()
458 /* AICCFIXFREQ0 NT N-1(Video rejection) */ in lgdt3306a_set_vsb()
463 /* AICCFIXFREQ1 NT N-1(Audio rejection) */ in lgdt3306a_set_vsb()
468 /* AICCFIXFREQ2 NT Co-Channel(Video rejection) */ in lgdt3306a_set_vsb()
473 /* AICCFIXFREQ3 NT Co-Channel(Audio rejection) */ in lgdt3306a_set_vsb()
593 /* 4. ADC sampling frequency rate(4x sampling) */ in lgdt3306a_set_qam()
623 /* 5.3 Fix for Blonder Tongue HDE-2H-QAM and AQM modulators */ in lgdt3306a_set_qam()
647 switch (p->modulation) { in lgdt3306a_set_modulation()
654 ret = lgdt3306a_set_qam(state, p->modulation); in lgdt3306a_set_modulation()
657 return -EINVAL; in lgdt3306a_set_modulation()
662 state->current_modulation = p->modulation; in lgdt3306a_set_modulation()
668 /* ------------------------------------------------------------------------ */
676 switch (p->modulation) { in lgdt3306a_agc_setup()
684 return -EINVAL; in lgdt3306a_agc_setup()
689 /* ------------------------------------------------------------------------ */
709 /* 0=Manual 1=Auto(QAM only) - SPECINVAUTO=0x04 */ in lgdt3306a_set_inversion_auto()
721 switch (p->modulation) { in lgdt3306a_set_if()
723 if_freq_khz = state->cfg->vsb_if_khz; in lgdt3306a_set_if()
728 if_freq_khz = state->cfg->qam_if_khz; in lgdt3306a_set_if()
731 return -EINVAL; in lgdt3306a_set_if()
767 dbg_info("if_freq=%d KHz->[%04x]\n", if_freq_khz, nco1<<8 | nco2); in lgdt3306a_set_if()
772 /* ------------------------------------------------------------------------ */
776 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_i2c_gate_ctrl()
778 if (state->cfg->deny_i2c_rptr) { in lgdt3306a_i2c_gate_ctrl()
779 dbg_info("deny_i2c_rptr=%d\n", state->cfg->deny_i2c_rptr); in lgdt3306a_i2c_gate_ctrl()
793 state->current_frequency = -1; /* force re-tune, when we wake */ in lgdt3306a_sleep()
808 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_fe_sleep()
815 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_init()
816 struct dtv_frontend_properties *c = &fe->dtv_property_cache; in lgdt3306a_init()
837 /* 4. Peak-to-peak voltage of ADC input signal */ in lgdt3306a_init()
851 /* 5a. ADC sampling clock source */ in lgdt3306a_init()
865 if (state->cfg->xtalMHz == 24) { /* 24MHz */ in lgdt3306a_init()
879 /* 8. ADC sampling frequency(0x180000 for 24MHz sampling) */ in lgdt3306a_init()
889 } else if (state->cfg->xtalMHz == 25) { /* 25MHz */ in lgdt3306a_init()
903 /* 8. ADC sampling frequency(0x190000 for 25MHz sampling) */ in lgdt3306a_init()
913 pr_err("Bad xtalMHz=%d\n", state->cfg->xtalMHz); in lgdt3306a_init()
955 /* FGR - put demod in some known mode */ in lgdt3306a_init()
959 ret = lgdt3306a_mpeg_mode(state, state->cfg->mpeg_mode); in lgdt3306a_init()
968 c->cnr.len = 1; in lgdt3306a_init()
969 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3306a_init()
977 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt3306a_set_parameters()
978 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_set_parameters()
981 dbg_info("(%d, %d)\n", p->frequency, p->modulation); in lgdt3306a_set_parameters()
983 if (state->current_frequency == p->frequency && in lgdt3306a_set_parameters()
984 state->current_modulation == p->modulation) { in lgdt3306a_set_parameters()
988 state->current_frequency = -1; in lgdt3306a_set_parameters()
989 state->current_modulation = -1; in lgdt3306a_set_parameters()
995 if (fe->ops.tuner_ops.set_params) { in lgdt3306a_set_parameters()
996 ret = fe->ops.tuner_ops.set_params(fe); in lgdt3306a_set_parameters()
997 if (fe->ops.i2c_gate_ctrl) in lgdt3306a_set_parameters()
998 fe->ops.i2c_gate_ctrl(fe, 0); in lgdt3306a_set_parameters()
1002 state->current_frequency = p->frequency; in lgdt3306a_set_parameters()
1020 ret = lgdt3306a_mpeg_mode(state, state->cfg->mpeg_mode); in lgdt3306a_set_parameters()
1025 state->cfg->tpclk_edge, in lgdt3306a_set_parameters()
1026 state->cfg->tpvalid_polarity); in lgdt3306a_set_parameters()
1041 state->current_frequency = p->frequency; in lgdt3306a_set_parameters()
1049 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_get_frontend()
1052 state->current_frequency, state->current_modulation); in lgdt3306a_get_frontend()
1054 p->modulation = state->current_modulation; in lgdt3306a_get_frontend()
1055 p->frequency = state->current_frequency; in lgdt3306a_get_frontend()
1068 /* ------------------------------------------------------------------------ */
1448 return -1000000; /* signal error */ in log10_x1000()
1456 log_val--; in log10_x1000()
1475 return log_val + log10x_x1000[i - 1]; in log10_x1000()
1477 diff_val = x - valx_x10[i-1]; in log10_x1000()
1478 step_val = valx_x10[i] - valx_x10[i - 1]; in log10_x1000()
1479 step_log10 = log10x_x1000[i] - log10x_x1000[i - 1]; in log10_x1000()
1481 /* do a linear interpolation to get in-between values */ in log10_x1000()
1482 return log_val + log10x_x1000[i - 1] + in log10_x1000()
1488 u32 mse; /* Mean-Square Error */ in lgdt3306a_calculate_snr_x100()
1500 snr_x100 = log10_x1000((pwr * 10000) / mse) - 3000; in lgdt3306a_calculate_snr_x100()
1567 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_read_status()
1568 struct dtv_frontend_properties *c = &fe->dtv_property_cache; in lgdt3306a_read_status()
1572 if (fe->ops.tuner_ops.get_rf_strength) { in lgdt3306a_read_status()
1573 ret = fe->ops.tuner_ops.get_rf_strength(fe, &strength); in lgdt3306a_read_status()
1577 dbg_info("fe->ops.tuner_ops.get_rf_strength() failed\n"); in lgdt3306a_read_status()
1585 switch (state->current_modulation) { in lgdt3306a_read_status()
1607 ret = -EINVAL; in lgdt3306a_read_status()
1611 c->cnr.len = 1; in lgdt3306a_read_status()
1612 c->cnr.stat[0].scale = FE_SCALE_DECIBEL; in lgdt3306a_read_status()
1613 c->cnr.stat[0].svalue = lgdt3306a_calculate_snr_x100(state) * 10; in lgdt3306a_read_status()
1615 c->cnr.len = 1; in lgdt3306a_read_status()
1616 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3306a_read_status()
1625 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_read_snr()
1627 state->snr = lgdt3306a_calculate_snr_x100(state); in lgdt3306a_read_snr()
1629 *snr = state->snr/10; in lgdt3306a_read_snr()
1640 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_read_signal_strength()
1649 switch (state->current_modulation) { in lgdt3306a_read_signal_strength()
1662 ref_snr = 2800; /* QAM-256 28dB */ in lgdt3306a_read_signal_strength()
1664 ref_snr = 2200; /* QAM-64 22dB */ in lgdt3306a_read_signal_strength()
1667 return -EINVAL; in lgdt3306a_read_signal_strength()
1670 ret = fe->ops.read_snr(fe, &snr); in lgdt3306a_read_signal_strength()
1674 if (state->snr <= (ref_snr - 100)) in lgdt3306a_read_signal_strength()
1676 else if (state->snr <= ref_snr) in lgdt3306a_read_signal_strength()
1679 str = state->snr - ref_snr; in lgdt3306a_read_signal_strength()
1681 str += 78; /* 78%-100% */ in lgdt3306a_read_signal_strength()
1693 /* ------------------------------------------------------------------------ */
1697 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_read_ber()
1702 /* FGR - FIXME - I don't know what value is expected by dvb_core in lgdt3306a_read_ber()
1704 tmp = read_reg(state, 0x00fc); /* NBERVALUE[24-31] */ in lgdt3306a_read_ber()
1705 tmp = (tmp << 8) | read_reg(state, 0x00fd); /* NBERVALUE[16-23] */ in lgdt3306a_read_ber()
1706 tmp = (tmp << 8) | read_reg(state, 0x00fe); /* NBERVALUE[8-15] */ in lgdt3306a_read_ber()
1707 tmp = (tmp << 8) | read_reg(state, 0x00ff); /* NBERVALUE[0-7] */ in lgdt3306a_read_ber()
1716 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_read_ucblocks()
1720 /* FGR - FIXME - I don't know what value is expected by dvb_core in lgdt3306a_read_ucblocks()
1722 *ucblocks = read_reg(state, 0x00f4); /* TPIFTPERRCNT[0-7] */ in lgdt3306a_read_ucblocks()
1734 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_tune()
1739 state->current_frequency = -1; /* force re-tune */ in lgdt3306a_tune()
1754 fe_tune_settings->min_delay_ms = 100; in lgdt3306a_get_tune_settings()
1786 struct lgdt3306a_state *state = fe->demodulator_priv; in lgdt3306a_release()
1801 dbg_info("(%d-%04x)\n", in lgdt3306a_attach()
1803 config ? config->i2c_addr : 0); in lgdt3306a_attach()
1809 state->cfg = config; in lgdt3306a_attach()
1810 state->i2c_adap = i2c_adap; in lgdt3306a_attach()
1812 memcpy(&state->frontend.ops, &lgdt3306a_ops, in lgdt3306a_attach()
1814 state->frontend.demodulator_priv = state; in lgdt3306a_attach()
1816 /* verify that we're talking to a lg3306a */ in lgdt3306a_attach()
1817 /* FGR - NOTE - there is no obvious ChipId to check; we check in lgdt3306a_attach()
1825 /* FIXME - re-enable when we know this is right */ in lgdt3306a_attach()
1835 /* FIXME - re-enable when we know this is right */ in lgdt3306a_attach()
1845 /* FIXME - re-enable when we know this is right */ in lgdt3306a_attach()
1850 state->current_frequency = -1; in lgdt3306a_attach()
1851 state->current_modulation = -1; in lgdt3306a_attach()
1855 return &state->frontend; in lgdt3306a_attach()
2161 return lgdt3306a_i2c_gate_ctrl(&state->frontend, 1); in lgdt3306a_select()
2169 return lgdt3306a_i2c_gate_ctrl(&state->frontend, 0); in lgdt3306a_deselect()
2179 if (!client->dev.platform_data) { in lgdt3306a_probe()
2180 dev_err(&client->dev, "platform data is mandatory\n"); in lgdt3306a_probe()
2181 return -EINVAL; in lgdt3306a_probe()
2184 config = kmemdup(client->dev.platform_data, in lgdt3306a_probe()
2187 ret = -ENOMEM; in lgdt3306a_probe()
2191 config->i2c_addr = client->addr; in lgdt3306a_probe()
2192 fe = lgdt3306a_attach(config, client->adapter); in lgdt3306a_probe()
2194 ret = -ENODEV; in lgdt3306a_probe()
2198 i2c_set_clientdata(client, fe->demodulator_priv); in lgdt3306a_probe()
2199 state = fe->demodulator_priv; in lgdt3306a_probe()
2200 state->frontend.ops.release = NULL; in lgdt3306a_probe()
2203 state->muxc = i2c_mux_alloc(client->adapter, &client->dev, in lgdt3306a_probe()
2206 if (!state->muxc) { in lgdt3306a_probe()
2207 ret = -ENOMEM; in lgdt3306a_probe()
2210 state->muxc->priv = client; in lgdt3306a_probe()
2211 ret = i2c_mux_add_adapter(state->muxc, 0, 0); in lgdt3306a_probe()
2216 fe->ops.i2c_gate_ctrl = NULL; in lgdt3306a_probe()
2217 *config->i2c_adapter = state->muxc->adapter[0]; in lgdt3306a_probe()
2218 *config->fe = fe; in lgdt3306a_probe()
2220 dev_info(&client->dev, "LG Electronics LGDT3306A successfully identified\n"); in lgdt3306a_probe()
2229 dev_warn(&client->dev, "probe failed = %d\n", ret); in lgdt3306a_probe()
2237 i2c_mux_del_adapters(state->muxc); in lgdt3306a_remove()
2239 state->frontend.ops.release = NULL; in lgdt3306a_remove()
2240 state->frontend.demodulator_priv = NULL; in lgdt3306a_remove()
2242 kfree(state->cfg); in lgdt3306a_remove()
2264 MODULE_DESCRIPTION("LG Electronics LGDT3306A ATSC/QAM-B Demodulator Driver");