Lines Matching +full:low +full:- +full:noise
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Support for LGDT3302 and LGDT3303 - VSB/QAM
12 * DViCO FusionHDTV 3 Gold-Q
13 * DViCO FusionHDTV 3 Gold-T
44 dev_printk(KERN_DEBUG, &state->client->dev, fmt, ##arg);\
72 for (i = 0; i < len - 1; i += 2) { in i2c_write_demod_bytes()
73 err = i2c_master_send(state->client, buf, 2); in i2c_write_demod_bytes()
75 dev_warn(&state->client->dev, in i2c_write_demod_bytes()
76 "%s: error (addr %02x <- %02x, err = %i)\n", in i2c_write_demod_bytes()
81 return -EREMOTEIO; in i2c_write_demod_bytes()
98 .addr = state->client->addr, in i2c_read_demod_bytes()
103 .addr = state->client->addr, in i2c_read_demod_bytes()
111 ret = i2c_transfer(state->client->adapter, msg, 2); in i2c_read_demod_bytes()
113 dev_warn(&state->client->dev, in i2c_read_demod_bytes()
115 __func__, state->client->addr, reg, ret); in i2c_read_demod_bytes()
117 ret = -EIO; in i2c_read_demod_bytes()
131 * bit 6 is active low software reset in lgdt3302_sw_reset()
132 * bits 5-0 are 1 to mask interrupts in lgdt3302_sw_reset()
153 0x00 /* bit 0 is active low software reset */ in lgdt3303_sw_reset()
169 switch (state->config.demod_chip) { in lgdt330x_sw_reset()
175 return -ENODEV; in lgdt330x_sw_reset()
181 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_init()
182 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt330x_init()
249 * cx88-cards.c arranges for the reset bit to be inactive (high). in lgdt330x_init()
250 * Maybe there needs to be a callable function in cx88-core or in lgdt330x_init()
254 switch (state->config.demod_chip) { in lgdt330x_init()
262 switch (state->config.clock_polarity_flip) { in lgdt330x_init()
281 dev_warn(&state->client->dev, in lgdt330x_init()
283 err = -ENODEV; in lgdt330x_init()
289 p->cnr.len = 1; in lgdt330x_init()
290 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt330x_init()
291 p->block_error.len = 1; in lgdt330x_init()
292 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt330x_init()
293 p->block_count.len = 1; in lgdt330x_init()
294 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt330x_init()
295 state->last_stats_time = 0; in lgdt330x_init()
302 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_read_ucblocks()
304 *ucblocks = state->ucblocks; in lgdt330x_read_ucblocks()
311 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt330x_set_parameters()
312 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_set_parameters()
346 if (state->current_modulation != p->modulation) { in lgdt330x_set_parameters()
347 switch (p->modulation) { in lgdt330x_set_parameters()
355 if (state->config.pll_rf_set) in lgdt330x_set_parameters()
356 state->config.pll_rf_set(fe, 1); in lgdt330x_set_parameters()
358 if (state->config.demod_chip == LGDT3303) { in lgdt330x_set_parameters()
372 if (state->config.pll_rf_set) in lgdt330x_set_parameters()
373 state->config.pll_rf_set(fe, 0); in lgdt330x_set_parameters()
375 if (state->config.demod_chip == LGDT3303) { in lgdt330x_set_parameters()
389 if (state->config.pll_rf_set) in lgdt330x_set_parameters()
390 state->config.pll_rf_set(fe, 0); in lgdt330x_set_parameters()
392 if (state->config.demod_chip == LGDT3303) { in lgdt330x_set_parameters()
399 dev_warn(&state->client->dev, in lgdt330x_set_parameters()
401 __func__, p->modulation); in lgdt330x_set_parameters()
402 return -1; in lgdt330x_set_parameters()
405 dev_warn(&state->client->dev, in lgdt330x_set_parameters()
407 __func__, p->modulation); in lgdt330x_set_parameters()
414 top_ctrl_cfg[1] |= state->config.serial_mpeg; in lgdt330x_set_parameters()
419 if (state->config.set_ts_params) in lgdt330x_set_parameters()
420 state->config.set_ts_params(fe, 0); in lgdt330x_set_parameters()
421 state->current_modulation = p->modulation; in lgdt330x_set_parameters()
425 if (fe->ops.tuner_ops.set_params) { in lgdt330x_set_parameters()
426 fe->ops.tuner_ops.set_params(fe); in lgdt330x_set_parameters()
427 if (fe->ops.i2c_gate_ctrl) in lgdt330x_set_parameters()
428 fe->ops.i2c_gate_ctrl(fe, 0); in lgdt330x_set_parameters()
436 state->current_frequency = p->frequency; in lgdt330x_set_parameters()
445 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_get_frontend()
447 p->frequency = state->current_frequency; in lgdt330x_get_frontend()
454 * 8-VSB SNR equations from LGDT3302 and LGDT3303 datasheets, QAM
459 * For 8-VSB: (two ways, take your pick)
466 * For 64-QAM:
468 * For 256-QAM:
471 * We re-write the snr equation as:
472 * SNR * 2^24 = 10*(c - intlog10(MSE))
473 * Where for 256-QAM, c = log10(696320) * 2^24, and so on.
489 return 10 * (c - mse); in calculate_snr()
494 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt3302_read_snr()
496 u32 noise; /* noise value */ in lgdt3302_read_snr() local
497 u32 c; /* per-modulation SNR calculation constant */ in lgdt3302_read_snr()
499 switch (state->current_modulation) { in lgdt3302_read_snr()
503 /* Use Equalizer Mean-Square Error Register */ in lgdt3302_read_snr()
504 /* SNR for ranges from -15.61 to +41.58 */ in lgdt3302_read_snr()
505 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2]; in lgdt3302_read_snr()
508 /* Use Phase Tracker Mean-Square Error Register */ in lgdt3302_read_snr()
509 /* SNR for ranges from -13.11 to +44.08 */ in lgdt3302_read_snr()
510 noise = ((buf[0] & 7 << 3) << 13) | (buf[3] << 8) | buf[4]; in lgdt3302_read_snr()
517 noise = ((buf[0] & 3) << 8) | buf[1]; in lgdt3302_read_snr()
518 c = state->current_modulation == QAM_64 ? 97939837 : 98026066; in lgdt3302_read_snr()
522 dev_err(&state->client->dev, in lgdt3302_read_snr()
526 state->snr = 0; in lgdt3302_read_snr()
528 return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */ in lgdt3302_read_snr()
531 state->snr = calculate_snr(noise, c); in lgdt3302_read_snr()
533 dprintk(state, "noise = 0x%08x, snr = %d.%02d dB\n", noise, in lgdt3302_read_snr()
534 state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16); in lgdt3302_read_snr()
541 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt3303_read_snr()
543 u32 noise; /* noise value */ in lgdt3303_read_snr() local
544 u32 c; /* per-modulation SNR calculation constant */ in lgdt3303_read_snr()
546 switch (state->current_modulation) { in lgdt3303_read_snr()
550 /* Use Equalizer Mean-Square Error Register */ in lgdt3303_read_snr()
551 /* SNR for ranges from -16.12 to +44.08 */ in lgdt3303_read_snr()
552 noise = ((buf[0] & 0x78) << 13) | (buf[1] << 8) | buf[2]; in lgdt3303_read_snr()
555 /* Use Phase Tracker Mean-Square Error Register */ in lgdt3303_read_snr()
556 /* SNR for ranges from -13.11 to +44.08 */ in lgdt3303_read_snr()
557 noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; in lgdt3303_read_snr()
564 noise = (buf[0] << 8) | buf[1]; in lgdt3303_read_snr()
565 c = state->current_modulation == QAM_64 ? 97939837 : 98026066; in lgdt3303_read_snr()
569 dev_err(&state->client->dev, in lgdt3303_read_snr()
572 state->snr = 0; in lgdt3303_read_snr()
573 return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */ in lgdt3303_read_snr()
576 state->snr = calculate_snr(noise, c); in lgdt3303_read_snr()
578 dprintk(state, "noise = 0x%08x, snr = %d.%02d dB\n", noise, in lgdt3303_read_snr()
579 state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16); in lgdt3303_read_snr()
586 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_read_snr()
588 *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */ in lgdt330x_read_snr()
600 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_read_signal_strength()
604 ret = fe->ops.read_snr(fe, &snr); in lgdt330x_read_signal_strength()
607 /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ in lgdt330x_read_signal_strength()
608 /* scale the range 0 - 35*2^24 into 0 - 65535 */ in lgdt330x_read_signal_strength()
609 if (state->snr >= 8960 * 0x10000) in lgdt330x_read_signal_strength()
612 *strength = state->snr / 8960; in lgdt330x_read_signal_strength()
621 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt3302_read_status()
622 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt3302_read_status()
662 switch (state->current_modulation) { in lgdt3302_read_status()
674 dev_warn(&state->client->dev, in lgdt3302_read_status()
680 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3302_read_status()
681 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3302_read_status()
682 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3302_read_status()
686 if (state->last_stats_time && in lgdt3302_read_status()
687 time_is_after_jiffies(state->last_stats_time)) in lgdt3302_read_status()
690 state->last_stats_time = jiffies + msecs_to_jiffies(1000); in lgdt3302_read_status()
694 p->cnr.stat[0].scale = FE_SCALE_DECIBEL; in lgdt3302_read_status()
695 p->cnr.stat[0].svalue = (((u64)state->snr) * 1000) >> 24; in lgdt3302_read_status()
697 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3302_read_status()
703 state->ucblocks = (buf[0] << 8) | buf[1]; in lgdt3302_read_status()
705 dprintk(state, "UCB = 0x%02x\n", state->ucblocks); in lgdt3302_read_status()
707 p->block_error.stat[0].uvalue += state->ucblocks; in lgdt3302_read_status()
709 p->block_count.stat[0].uvalue += 10000; in lgdt3302_read_status()
711 p->block_error.stat[0].scale = FE_SCALE_COUNTER; in lgdt3302_read_status()
712 p->block_count.stat[0].scale = FE_SCALE_COUNTER; in lgdt3302_read_status()
714 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3302_read_status()
715 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3302_read_status()
724 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt3303_read_status()
725 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt3303_read_status()
748 switch (state->current_modulation) { in lgdt3303_read_status()
772 dprintk(state, "8-VSB LOCK = 0x%02x\n", buf[0]); in lgdt3303_read_status()
780 dev_warn(&state->client->dev, in lgdt3303_read_status()
786 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3303_read_status()
787 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3303_read_status()
788 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3303_read_status()
792 if (state->last_stats_time && in lgdt3303_read_status()
793 time_is_after_jiffies(state->last_stats_time)) in lgdt3303_read_status()
796 state->last_stats_time = jiffies + msecs_to_jiffies(1000); in lgdt3303_read_status()
800 p->cnr.stat[0].scale = FE_SCALE_DECIBEL; in lgdt3303_read_status()
801 p->cnr.stat[0].svalue = (((u64)state->snr) * 1000) >> 24; in lgdt3303_read_status()
803 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3303_read_status()
809 state->ucblocks = (buf[0] << 8) | buf[1]; in lgdt3303_read_status()
811 dprintk(state, "UCB = 0x%02x\n", state->ucblocks); in lgdt3303_read_status()
813 p->block_error.stat[0].uvalue += state->ucblocks; in lgdt3303_read_status()
815 p->block_count.stat[0].uvalue += 10000; in lgdt3303_read_status()
817 p->block_error.stat[0].scale = FE_SCALE_COUNTER; in lgdt3303_read_status()
818 p->block_count.stat[0].scale = FE_SCALE_COUNTER; in lgdt3303_read_status()
820 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3303_read_status()
821 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in lgdt3303_read_status()
831 /* I have no idea about this - it may not be needed */ in lgdt330x_get_tune_settings()
832 fe_tune_settings->min_delay_ms = 500; in lgdt330x_get_tune_settings()
833 fe_tune_settings->step_size = 0; in lgdt330x_get_tune_settings()
834 fe_tune_settings->max_drift = 0; in lgdt330x_get_tune_settings()
840 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_release()
841 struct i2c_client *client = state->client; in lgdt330x_release()
843 dev_dbg(&client->dev, "\n"); in lgdt330x_release()
852 dev_dbg(&client->dev, "\n"); in lgdt330x_get_dvb_frontend()
854 return &state->frontend; in lgdt330x_get_dvb_frontend()
871 memcpy(&state->config, client->dev.platform_data, in lgdt330x_probe()
872 sizeof(state->config)); in lgdt330x_probe()
874 state->client = client; in lgdt330x_probe()
877 switch (state->config.demod_chip) { in lgdt330x_probe()
879 memcpy(&state->frontend.ops, &lgdt3302_ops, in lgdt330x_probe()
883 memcpy(&state->frontend.ops, &lgdt3303_ops, in lgdt330x_probe()
889 state->frontend.demodulator_priv = state; in lgdt330x_probe()
892 state->config.get_dvb_frontend = lgdt330x_get_dvb_frontend; in lgdt330x_probe()
898 state->current_frequency = -1; in lgdt330x_probe()
899 state->current_modulation = -1; in lgdt330x_probe()
901 dev_info(&state->client->dev, in lgdt330x_probe()
903 state->config.demod_chip == LGDT3302 ? "2" : "3"); in lgdt330x_probe()
910 dev_printk(KERN_DEBUG, &client->dev, "Error loading lgdt330x driver\n"); in lgdt330x_probe()
911 return -ENODEV; in lgdt330x_probe()
980 dev_dbg(&client->dev, "\n"); in lgdt330x_remove()
1004 MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");