Lines Matching +full:p +full:- +full:state
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
42 #define dprintk(state, fmt, arg...) do { \ argument
44 dev_printk(KERN_DEBUG, &state->client->dev, fmt, ##arg);\
65 static int i2c_write_demod_bytes(struct lgdt330x_state *state, in i2c_write_demod_bytes() argument
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()
92 static int i2c_read_demod_bytes(struct lgdt330x_state *state, in i2c_read_demod_bytes() argument
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()
125 static int lgdt3302_sw_reset(struct lgdt330x_state *state) in lgdt3302_sw_reset() argument
132 * bits 5-0 are 1 to mask interrupts in lgdt3302_sw_reset()
137 ret = i2c_write_demod_bytes(state, in lgdt3302_sw_reset()
142 ret = i2c_write_demod_bytes(state, in lgdt3302_sw_reset()
148 static int lgdt3303_sw_reset(struct lgdt330x_state *state) in lgdt3303_sw_reset() argument
156 ret = i2c_write_demod_bytes(state, in lgdt3303_sw_reset()
161 ret = i2c_write_demod_bytes(state, in lgdt3303_sw_reset()
167 static int lgdt330x_sw_reset(struct lgdt330x_state *state) in lgdt330x_sw_reset() argument
169 switch (state->config.demod_chip) { in lgdt330x_sw_reset()
171 return lgdt3302_sw_reset(state); in lgdt330x_sw_reset()
173 return lgdt3303_sw_reset(state); in lgdt330x_sw_reset()
175 return -ENODEV; in lgdt330x_sw_reset()
181 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_init() local
182 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt330x_init() local
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()
257 err = i2c_write_demod_bytes(state, lgdt3302_init_data, in lgdt330x_init()
262 switch (state->config.clock_polarity_flip) { in lgdt330x_init()
264 err = i2c_write_demod_bytes(state, in lgdt330x_init()
269 err = i2c_write_demod_bytes(state, in lgdt330x_init()
275 err = i2c_write_demod_bytes(state, lgdt3303_init_data, in lgdt330x_init()
281 dev_warn(&state->client->dev, in lgdt330x_init()
283 err = -ENODEV; in lgdt330x_init()
285 dprintk(state, "Initialized the %s chip\n", chip_name); 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()
297 return lgdt330x_sw_reset(state); in lgdt330x_init()
302 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_read_ucblocks() local
304 *ucblocks = state->ucblocks; in lgdt330x_read_ucblocks()
311 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt330x_set_parameters() local
312 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_set_parameters() local
346 if (state->current_modulation != p->modulation) { in lgdt330x_set_parameters()
347 switch (p->modulation) { in lgdt330x_set_parameters()
349 dprintk(state, "VSB_8 MODE\n"); 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()
359 err = i2c_write_demod_bytes(state, in lgdt330x_set_parameters()
366 dprintk(state, "QAM_64 MODE\n"); 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()
376 err = i2c_write_demod_bytes(state, in lgdt330x_set_parameters()
383 dprintk(state, "QAM_256 MODE\n"); 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()
393 err = i2c_write_demod_bytes(state, 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()
417 i2c_write_demod_bytes(state, top_ctrl_cfg, 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()
438 lgdt330x_sw_reset(state); in lgdt330x_set_parameters()
443 struct dtv_frontend_properties *p) in lgdt330x_get_frontend() argument
445 struct lgdt330x_state *state = fe->demodulator_priv; in lgdt330x_get_frontend() local
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() local
497 u32 c; /* per-modulation SNR calculation constant */ in lgdt3302_read_snr()
499 switch (state->current_modulation) { in lgdt3302_read_snr()
501 i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf, 5); 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()
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()
516 i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2); 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() local
544 u32 c; /* per-modulation SNR calculation constant */ in lgdt3303_read_snr()
546 switch (state->current_modulation) { in lgdt3303_read_snr()
548 i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf, 5); 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()
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()
563 i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2); 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() local
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() local
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() local
622 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt3302_read_status() local
629 i2c_read_demod_bytes(state, AGC_STATUS, buf, 1); in lgdt3302_read_status()
630 dprintk(state, "AGC_STATUS = 0x%02x\n", buf[0]); in lgdt3302_read_status()
646 i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf)); in lgdt3302_read_status()
647 dprintk(state, in lgdt3302_read_status()
660 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); in lgdt3302_read_status()
661 dprintk(state, "CARRIER_LOCK = 0x%02x\n", buf[0]); 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()
700 err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1, 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() local
725 struct dtv_frontend_properties *p = &fe->dtv_property_cache; in lgdt3303_read_status() local
732 err = i2c_read_demod_bytes(state, 0x58, buf, 1); in lgdt3303_read_status()
736 dprintk(state, "AGC_STATUS = 0x%02x\n", buf[0]); in lgdt3303_read_status()
746 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); in lgdt3303_read_status()
747 dprintk(state, "CARRIER_LOCK = 0x%02x\n", buf[0]); in lgdt3303_read_status()
748 switch (state->current_modulation) { in lgdt3303_read_status()
756 i2c_read_demod_bytes(state, 0x8a, buf, 1); in lgdt3303_read_status()
757 dprintk(state, "QAM LOCK = 0x%02x\n", buf[0]); in lgdt3303_read_status()
771 i2c_read_demod_bytes(state, 0x38, buf, 1); 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()
806 err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1, 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() local
841 struct i2c_client *client = state->client; in lgdt330x_release()
843 dev_dbg(&client->dev, "\n"); in lgdt330x_release()
850 struct lgdt330x_state *state = i2c_get_clientdata(client); in lgdt330x_get_dvb_frontend() local
852 dev_dbg(&client->dev, "\n"); in lgdt330x_get_dvb_frontend()
854 return &state->frontend; in lgdt330x_get_dvb_frontend()
862 struct lgdt330x_state *state = NULL; in lgdt330x_probe() local
865 /* Allocate memory for the internal state */ in lgdt330x_probe()
866 state = kzalloc(sizeof(*state), GFP_KERNEL); in lgdt330x_probe()
867 if (!state) in lgdt330x_probe()
870 /* Setup the state */ in lgdt330x_probe()
871 memcpy(&state->config, client->dev.platform_data, in lgdt330x_probe()
872 sizeof(state->config)); in lgdt330x_probe()
873 i2c_set_clientdata(client, state); 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()
895 if (i2c_read_demod_bytes(state, 2, buf, 1)) 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()
908 kfree(state); in lgdt330x_probe()
910 dev_printk(KERN_DEBUG, &client->dev, "Error loading lgdt330x driver\n"); in lgdt330x_probe()
911 return -ENODEV; in lgdt330x_probe()
978 struct lgdt330x_state *state = i2c_get_clientdata(client); in lgdt330x_remove() local
980 dev_dbg(&client->dev, "\n"); in lgdt330x_remove()
982 kfree(state); in lgdt330x_remove()
1004 MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");