1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Support for LGDT3302 and LGDT3303 - VSB/QAM
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun * NOTES ABOUT THIS DRIVER
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * This Linux driver supports:
12*4882a593Smuzhiyun * DViCO FusionHDTV 3 Gold-Q
13*4882a593Smuzhiyun * DViCO FusionHDTV 3 Gold-T
14*4882a593Smuzhiyun * DViCO FusionHDTV 5 Gold
15*4882a593Smuzhiyun * DViCO FusionHDTV 5 Lite
16*4882a593Smuzhiyun * DViCO FusionHDTV 5 USB Gold
17*4882a593Smuzhiyun * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
18*4882a593Smuzhiyun * pcHDTV HD5500
19*4882a593Smuzhiyun *
20*4882a593Smuzhiyun */
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun #include <linux/kernel.h>
23*4882a593Smuzhiyun #include <linux/module.h>
24*4882a593Smuzhiyun #include <linux/init.h>
25*4882a593Smuzhiyun #include <linux/delay.h>
26*4882a593Smuzhiyun #include <linux/string.h>
27*4882a593Smuzhiyun #include <linux/slab.h>
28*4882a593Smuzhiyun #include <asm/byteorder.h>
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #include <media/dvb_frontend.h>
31*4882a593Smuzhiyun #include <media/dvb_math.h>
32*4882a593Smuzhiyun #include "lgdt330x_priv.h"
33*4882a593Smuzhiyun #include "lgdt330x.h"
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun /* Use Equalizer Mean Squared Error instead of Phaser Tracker MSE */
36*4882a593Smuzhiyun /* #define USE_EQMSE */
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun static int debug;
39*4882a593Smuzhiyun module_param(debug, int, 0644);
40*4882a593Smuzhiyun MODULE_PARM_DESC(debug, "Turn on/off lgdt330x frontend debugging (default:off).");
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun #define dprintk(state, fmt, arg...) do { \
43*4882a593Smuzhiyun if (debug) \
44*4882a593Smuzhiyun dev_printk(KERN_DEBUG, &state->client->dev, fmt, ##arg);\
45*4882a593Smuzhiyun } while (0)
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun struct lgdt330x_state {
48*4882a593Smuzhiyun struct i2c_client *client;
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun /* Configuration settings */
51*4882a593Smuzhiyun struct lgdt330x_config config;
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun struct dvb_frontend frontend;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /* Demodulator private data */
56*4882a593Smuzhiyun enum fe_modulation current_modulation;
57*4882a593Smuzhiyun u32 snr; /* Result of last SNR calculation */
58*4882a593Smuzhiyun u16 ucblocks;
59*4882a593Smuzhiyun unsigned long last_stats_time;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* Tuner private data */
62*4882a593Smuzhiyun u32 current_frequency;
63*4882a593Smuzhiyun };
64*4882a593Smuzhiyun
i2c_write_demod_bytes(struct lgdt330x_state * state,const u8 * buf,int len)65*4882a593Smuzhiyun static int i2c_write_demod_bytes(struct lgdt330x_state *state,
66*4882a593Smuzhiyun const u8 *buf, /* data bytes to send */
67*4882a593Smuzhiyun int len /* number of bytes to send */)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun int i;
70*4882a593Smuzhiyun int err;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun for (i = 0; i < len - 1; i += 2) {
73*4882a593Smuzhiyun err = i2c_master_send(state->client, buf, 2);
74*4882a593Smuzhiyun if (err != 2) {
75*4882a593Smuzhiyun dev_warn(&state->client->dev,
76*4882a593Smuzhiyun "%s: error (addr %02x <- %02x, err = %i)\n",
77*4882a593Smuzhiyun __func__, buf[0], buf[1], err);
78*4882a593Smuzhiyun if (err < 0)
79*4882a593Smuzhiyun return err;
80*4882a593Smuzhiyun else
81*4882a593Smuzhiyun return -EREMOTEIO;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun buf += 2;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun return 0;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun /*
89*4882a593Smuzhiyun * This routine writes the register (reg) to the demod bus
90*4882a593Smuzhiyun * then reads the data returned for (len) bytes.
91*4882a593Smuzhiyun */
i2c_read_demod_bytes(struct lgdt330x_state * state,enum I2C_REG reg,u8 * buf,int len)92*4882a593Smuzhiyun static int i2c_read_demod_bytes(struct lgdt330x_state *state,
93*4882a593Smuzhiyun enum I2C_REG reg, u8 *buf, int len)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun u8 wr[] = { reg };
96*4882a593Smuzhiyun struct i2c_msg msg[] = {
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun .addr = state->client->addr,
99*4882a593Smuzhiyun .flags = 0,
100*4882a593Smuzhiyun .buf = wr,
101*4882a593Smuzhiyun .len = 1
102*4882a593Smuzhiyun }, {
103*4882a593Smuzhiyun .addr = state->client->addr,
104*4882a593Smuzhiyun .flags = I2C_M_RD,
105*4882a593Smuzhiyun .buf = buf,
106*4882a593Smuzhiyun .len = len
107*4882a593Smuzhiyun },
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun int ret;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun ret = i2c_transfer(state->client->adapter, msg, 2);
112*4882a593Smuzhiyun if (ret != 2) {
113*4882a593Smuzhiyun dev_warn(&state->client->dev,
114*4882a593Smuzhiyun "%s: addr 0x%02x select 0x%02x error (ret == %i)\n",
115*4882a593Smuzhiyun __func__, state->client->addr, reg, ret);
116*4882a593Smuzhiyun if (ret >= 0)
117*4882a593Smuzhiyun ret = -EIO;
118*4882a593Smuzhiyun } else {
119*4882a593Smuzhiyun ret = 0;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun return ret;
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun /* Software reset */
lgdt3302_sw_reset(struct lgdt330x_state * state)125*4882a593Smuzhiyun static int lgdt3302_sw_reset(struct lgdt330x_state *state)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun u8 ret;
128*4882a593Smuzhiyun u8 reset[] = {
129*4882a593Smuzhiyun IRQ_MASK,
130*4882a593Smuzhiyun /*
131*4882a593Smuzhiyun * bit 6 is active low software reset
132*4882a593Smuzhiyun * bits 5-0 are 1 to mask interrupts
133*4882a593Smuzhiyun */
134*4882a593Smuzhiyun 0x00
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun ret = i2c_write_demod_bytes(state,
138*4882a593Smuzhiyun reset, sizeof(reset));
139*4882a593Smuzhiyun if (ret == 0) {
140*4882a593Smuzhiyun /* force reset high (inactive) and unmask interrupts */
141*4882a593Smuzhiyun reset[1] = 0x7f;
142*4882a593Smuzhiyun ret = i2c_write_demod_bytes(state,
143*4882a593Smuzhiyun reset, sizeof(reset));
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun return ret;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
lgdt3303_sw_reset(struct lgdt330x_state * state)148*4882a593Smuzhiyun static int lgdt3303_sw_reset(struct lgdt330x_state *state)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun u8 ret;
151*4882a593Smuzhiyun u8 reset[] = {
152*4882a593Smuzhiyun 0x02,
153*4882a593Smuzhiyun 0x00 /* bit 0 is active low software reset */
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun ret = i2c_write_demod_bytes(state,
157*4882a593Smuzhiyun reset, sizeof(reset));
158*4882a593Smuzhiyun if (ret == 0) {
159*4882a593Smuzhiyun /* force reset high (inactive) */
160*4882a593Smuzhiyun reset[1] = 0x01;
161*4882a593Smuzhiyun ret = i2c_write_demod_bytes(state,
162*4882a593Smuzhiyun reset, sizeof(reset));
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun return ret;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
lgdt330x_sw_reset(struct lgdt330x_state * state)167*4882a593Smuzhiyun static int lgdt330x_sw_reset(struct lgdt330x_state *state)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun switch (state->config.demod_chip) {
170*4882a593Smuzhiyun case LGDT3302:
171*4882a593Smuzhiyun return lgdt3302_sw_reset(state);
172*4882a593Smuzhiyun case LGDT3303:
173*4882a593Smuzhiyun return lgdt3303_sw_reset(state);
174*4882a593Smuzhiyun default:
175*4882a593Smuzhiyun return -ENODEV;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun
lgdt330x_init(struct dvb_frontend * fe)179*4882a593Smuzhiyun static int lgdt330x_init(struct dvb_frontend *fe)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
182*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
183*4882a593Smuzhiyun char *chip_name;
184*4882a593Smuzhiyun int err;
185*4882a593Smuzhiyun /*
186*4882a593Smuzhiyun * Array of byte pairs <address, value>
187*4882a593Smuzhiyun * to initialize each different chip
188*4882a593Smuzhiyun */
189*4882a593Smuzhiyun static const u8 lgdt3302_init_data[] = {
190*4882a593Smuzhiyun /* Use 50MHz param values from spec sheet since xtal is 50 */
191*4882a593Smuzhiyun /*
192*4882a593Smuzhiyun * Change the value of NCOCTFV[25:0] of carrier
193*4882a593Smuzhiyun * recovery center frequency register
194*4882a593Smuzhiyun */
195*4882a593Smuzhiyun VSB_CARRIER_FREQ0, 0x00,
196*4882a593Smuzhiyun VSB_CARRIER_FREQ1, 0x87,
197*4882a593Smuzhiyun VSB_CARRIER_FREQ2, 0x8e,
198*4882a593Smuzhiyun VSB_CARRIER_FREQ3, 0x01,
199*4882a593Smuzhiyun /*
200*4882a593Smuzhiyun * Change the TPCLK pin polarity
201*4882a593Smuzhiyun * data is valid on falling clock
202*4882a593Smuzhiyun */
203*4882a593Smuzhiyun DEMUX_CONTROL, 0xfb,
204*4882a593Smuzhiyun /*
205*4882a593Smuzhiyun * Change the value of IFBW[11:0] of
206*4882a593Smuzhiyun * AGC IF/RF loop filter bandwidth register
207*4882a593Smuzhiyun */
208*4882a593Smuzhiyun AGC_RF_BANDWIDTH0, 0x40,
209*4882a593Smuzhiyun AGC_RF_BANDWIDTH1, 0x93,
210*4882a593Smuzhiyun AGC_RF_BANDWIDTH2, 0x00,
211*4882a593Smuzhiyun /*
212*4882a593Smuzhiyun * Change the value of bit 6, 'nINAGCBY' and
213*4882a593Smuzhiyun * 'NSSEL[1:0] of ACG function control register 2
214*4882a593Smuzhiyun */
215*4882a593Smuzhiyun AGC_FUNC_CTRL2, 0xc6,
216*4882a593Smuzhiyun /*
217*4882a593Smuzhiyun * Change the value of bit 6 'RFFIX'
218*4882a593Smuzhiyun * of AGC function control register 3
219*4882a593Smuzhiyun */
220*4882a593Smuzhiyun AGC_FUNC_CTRL3, 0x40,
221*4882a593Smuzhiyun /*
222*4882a593Smuzhiyun * Set the value of 'INLVTHD' register 0x2a/0x2c
223*4882a593Smuzhiyun * to 0x7fe
224*4882a593Smuzhiyun */
225*4882a593Smuzhiyun AGC_DELAY0, 0x07,
226*4882a593Smuzhiyun AGC_DELAY2, 0xfe,
227*4882a593Smuzhiyun /*
228*4882a593Smuzhiyun * Change the value of IAGCBW[15:8]
229*4882a593Smuzhiyun * of inner AGC loop filter bandwidth
230*4882a593Smuzhiyun */
231*4882a593Smuzhiyun AGC_LOOP_BANDWIDTH0, 0x08,
232*4882a593Smuzhiyun AGC_LOOP_BANDWIDTH1, 0x9a
233*4882a593Smuzhiyun };
234*4882a593Smuzhiyun static const u8 lgdt3303_init_data[] = {
235*4882a593Smuzhiyun 0x4c, 0x14
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun static const u8 flip_1_lgdt3303_init_data[] = {
238*4882a593Smuzhiyun 0x4c, 0x14,
239*4882a593Smuzhiyun 0x87, 0xf3
240*4882a593Smuzhiyun };
241*4882a593Smuzhiyun static const u8 flip_2_lgdt3303_init_data[] = {
242*4882a593Smuzhiyun 0x4c, 0x14,
243*4882a593Smuzhiyun 0x87, 0xda
244*4882a593Smuzhiyun };
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun /*
247*4882a593Smuzhiyun * Hardware reset is done using gpio[0] of cx23880x chip.
248*4882a593Smuzhiyun * I'd like to do it here, but don't know how to find chip address.
249*4882a593Smuzhiyun * cx88-cards.c arranges for the reset bit to be inactive (high).
250*4882a593Smuzhiyun * Maybe there needs to be a callable function in cx88-core or
251*4882a593Smuzhiyun * the caller of this function needs to do it.
252*4882a593Smuzhiyun */
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun switch (state->config.demod_chip) {
255*4882a593Smuzhiyun case LGDT3302:
256*4882a593Smuzhiyun chip_name = "LGDT3302";
257*4882a593Smuzhiyun err = i2c_write_demod_bytes(state, lgdt3302_init_data,
258*4882a593Smuzhiyun sizeof(lgdt3302_init_data));
259*4882a593Smuzhiyun break;
260*4882a593Smuzhiyun case LGDT3303:
261*4882a593Smuzhiyun chip_name = "LGDT3303";
262*4882a593Smuzhiyun switch (state->config.clock_polarity_flip) {
263*4882a593Smuzhiyun case 2:
264*4882a593Smuzhiyun err = i2c_write_demod_bytes(state,
265*4882a593Smuzhiyun flip_2_lgdt3303_init_data,
266*4882a593Smuzhiyun sizeof(flip_2_lgdt3303_init_data));
267*4882a593Smuzhiyun break;
268*4882a593Smuzhiyun case 1:
269*4882a593Smuzhiyun err = i2c_write_demod_bytes(state,
270*4882a593Smuzhiyun flip_1_lgdt3303_init_data,
271*4882a593Smuzhiyun sizeof(flip_1_lgdt3303_init_data));
272*4882a593Smuzhiyun break;
273*4882a593Smuzhiyun case 0:
274*4882a593Smuzhiyun default:
275*4882a593Smuzhiyun err = i2c_write_demod_bytes(state, lgdt3303_init_data,
276*4882a593Smuzhiyun sizeof(lgdt3303_init_data));
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun break;
279*4882a593Smuzhiyun default:
280*4882a593Smuzhiyun chip_name = "undefined";
281*4882a593Smuzhiyun dev_warn(&state->client->dev,
282*4882a593Smuzhiyun "Only LGDT3302 and LGDT3303 are supported chips.\n");
283*4882a593Smuzhiyun err = -ENODEV;
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun dprintk(state, "Initialized the %s chip\n", chip_name);
286*4882a593Smuzhiyun if (err < 0)
287*4882a593Smuzhiyun return err;
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun p->cnr.len = 1;
290*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
291*4882a593Smuzhiyun p->block_error.len = 1;
292*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
293*4882a593Smuzhiyun p->block_count.len = 1;
294*4882a593Smuzhiyun p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
295*4882a593Smuzhiyun state->last_stats_time = 0;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun return lgdt330x_sw_reset(state);
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun
lgdt330x_read_ucblocks(struct dvb_frontend * fe,u32 * ucblocks)300*4882a593Smuzhiyun static int lgdt330x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun *ucblocks = state->ucblocks;
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun return 0;
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun
lgdt330x_set_parameters(struct dvb_frontend * fe)309*4882a593Smuzhiyun static int lgdt330x_set_parameters(struct dvb_frontend *fe)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
312*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
313*4882a593Smuzhiyun /*
314*4882a593Smuzhiyun * Array of byte pairs <address, value>
315*4882a593Smuzhiyun * to initialize 8VSB for lgdt3303 chip 50 MHz IF
316*4882a593Smuzhiyun */
317*4882a593Smuzhiyun static const u8 lgdt3303_8vsb_44_data[] = {
318*4882a593Smuzhiyun 0x04, 0x00,
319*4882a593Smuzhiyun 0x0d, 0x40,
320*4882a593Smuzhiyun 0x0e, 0x87,
321*4882a593Smuzhiyun 0x0f, 0x8e,
322*4882a593Smuzhiyun 0x10, 0x01,
323*4882a593Smuzhiyun 0x47, 0x8b
324*4882a593Smuzhiyun };
325*4882a593Smuzhiyun /*
326*4882a593Smuzhiyun * Array of byte pairs <address, value>
327*4882a593Smuzhiyun * to initialize QAM for lgdt3303 chip
328*4882a593Smuzhiyun */
329*4882a593Smuzhiyun static const u8 lgdt3303_qam_data[] = {
330*4882a593Smuzhiyun 0x04, 0x00,
331*4882a593Smuzhiyun 0x0d, 0x00,
332*4882a593Smuzhiyun 0x0e, 0x00,
333*4882a593Smuzhiyun 0x0f, 0x00,
334*4882a593Smuzhiyun 0x10, 0x00,
335*4882a593Smuzhiyun 0x51, 0x63,
336*4882a593Smuzhiyun 0x47, 0x66,
337*4882a593Smuzhiyun 0x48, 0x66,
338*4882a593Smuzhiyun 0x4d, 0x1a,
339*4882a593Smuzhiyun 0x49, 0x08,
340*4882a593Smuzhiyun 0x4a, 0x9b
341*4882a593Smuzhiyun };
342*4882a593Smuzhiyun u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun int err = 0;
345*4882a593Smuzhiyun /* Change only if we are actually changing the modulation */
346*4882a593Smuzhiyun if (state->current_modulation != p->modulation) {
347*4882a593Smuzhiyun switch (p->modulation) {
348*4882a593Smuzhiyun case VSB_8:
349*4882a593Smuzhiyun dprintk(state, "VSB_8 MODE\n");
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun /* Select VSB mode */
352*4882a593Smuzhiyun top_ctrl_cfg[1] = 0x03;
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun /* Select ANT connector if supported by card */
355*4882a593Smuzhiyun if (state->config.pll_rf_set)
356*4882a593Smuzhiyun state->config.pll_rf_set(fe, 1);
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun if (state->config.demod_chip == LGDT3303) {
359*4882a593Smuzhiyun err = i2c_write_demod_bytes(state,
360*4882a593Smuzhiyun lgdt3303_8vsb_44_data,
361*4882a593Smuzhiyun sizeof(lgdt3303_8vsb_44_data));
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun break;
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun case QAM_64:
366*4882a593Smuzhiyun dprintk(state, "QAM_64 MODE\n");
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun /* Select QAM_64 mode */
369*4882a593Smuzhiyun top_ctrl_cfg[1] = 0x00;
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun /* Select CABLE connector if supported by card */
372*4882a593Smuzhiyun if (state->config.pll_rf_set)
373*4882a593Smuzhiyun state->config.pll_rf_set(fe, 0);
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun if (state->config.demod_chip == LGDT3303) {
376*4882a593Smuzhiyun err = i2c_write_demod_bytes(state,
377*4882a593Smuzhiyun lgdt3303_qam_data,
378*4882a593Smuzhiyun sizeof(lgdt3303_qam_data));
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun break;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun case QAM_256:
383*4882a593Smuzhiyun dprintk(state, "QAM_256 MODE\n");
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun /* Select QAM_256 mode */
386*4882a593Smuzhiyun top_ctrl_cfg[1] = 0x01;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun /* Select CABLE connector if supported by card */
389*4882a593Smuzhiyun if (state->config.pll_rf_set)
390*4882a593Smuzhiyun state->config.pll_rf_set(fe, 0);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun if (state->config.demod_chip == LGDT3303) {
393*4882a593Smuzhiyun err = i2c_write_demod_bytes(state,
394*4882a593Smuzhiyun lgdt3303_qam_data,
395*4882a593Smuzhiyun sizeof(lgdt3303_qam_data));
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun break;
398*4882a593Smuzhiyun default:
399*4882a593Smuzhiyun dev_warn(&state->client->dev,
400*4882a593Smuzhiyun "%s: Modulation type(%d) UNSUPPORTED\n",
401*4882a593Smuzhiyun __func__, p->modulation);
402*4882a593Smuzhiyun return -1;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun if (err < 0)
405*4882a593Smuzhiyun dev_warn(&state->client->dev,
406*4882a593Smuzhiyun "%s: error blasting bytes to lgdt3303 for modulation type(%d)\n",
407*4882a593Smuzhiyun __func__, p->modulation);
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun /*
410*4882a593Smuzhiyun * select serial or parallel MPEG hardware interface
411*4882a593Smuzhiyun * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303
412*4882a593Smuzhiyun * Parallel: 0x00
413*4882a593Smuzhiyun */
414*4882a593Smuzhiyun top_ctrl_cfg[1] |= state->config.serial_mpeg;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun /* Select the requested mode */
417*4882a593Smuzhiyun i2c_write_demod_bytes(state, top_ctrl_cfg,
418*4882a593Smuzhiyun sizeof(top_ctrl_cfg));
419*4882a593Smuzhiyun if (state->config.set_ts_params)
420*4882a593Smuzhiyun state->config.set_ts_params(fe, 0);
421*4882a593Smuzhiyun state->current_modulation = p->modulation;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun /* Tune to the specified frequency */
425*4882a593Smuzhiyun if (fe->ops.tuner_ops.set_params) {
426*4882a593Smuzhiyun fe->ops.tuner_ops.set_params(fe);
427*4882a593Smuzhiyun if (fe->ops.i2c_gate_ctrl)
428*4882a593Smuzhiyun fe->ops.i2c_gate_ctrl(fe, 0);
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun /* Keep track of the new frequency */
432*4882a593Smuzhiyun /*
433*4882a593Smuzhiyun * FIXME this is the wrong way to do this...
434*4882a593Smuzhiyun * The tuner is shared with the video4linux analog API
435*4882a593Smuzhiyun */
436*4882a593Smuzhiyun state->current_frequency = p->frequency;
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun lgdt330x_sw_reset(state);
439*4882a593Smuzhiyun return 0;
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun
lgdt330x_get_frontend(struct dvb_frontend * fe,struct dtv_frontend_properties * p)442*4882a593Smuzhiyun static int lgdt330x_get_frontend(struct dvb_frontend *fe,
443*4882a593Smuzhiyun struct dtv_frontend_properties *p)
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun p->frequency = state->current_frequency;
448*4882a593Smuzhiyun return 0;
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun /*
452*4882a593Smuzhiyun * Calculate SNR estimation (scaled by 2^24)
453*4882a593Smuzhiyun *
454*4882a593Smuzhiyun * 8-VSB SNR equations from LGDT3302 and LGDT3303 datasheets, QAM
455*4882a593Smuzhiyun * equations from LGDT3303 datasheet. VSB is the same between the '02
456*4882a593Smuzhiyun * and '03, so maybe QAM is too? Perhaps someone with a newer datasheet
457*4882a593Smuzhiyun * that has QAM information could verify?
458*4882a593Smuzhiyun *
459*4882a593Smuzhiyun * For 8-VSB: (two ways, take your pick)
460*4882a593Smuzhiyun * LGDT3302:
461*4882a593Smuzhiyun * SNR_EQ = 10 * log10(25 * 24^2 / EQ_MSE)
462*4882a593Smuzhiyun * LGDT3303:
463*4882a593Smuzhiyun * SNR_EQ = 10 * log10(25 * 32^2 / EQ_MSE)
464*4882a593Smuzhiyun * LGDT3302 & LGDT3303:
465*4882a593Smuzhiyun * SNR_PT = 10 * log10(25 * 32^2 / PT_MSE) (we use this one)
466*4882a593Smuzhiyun * For 64-QAM:
467*4882a593Smuzhiyun * SNR = 10 * log10( 688128 / MSEQAM)
468*4882a593Smuzhiyun * For 256-QAM:
469*4882a593Smuzhiyun * SNR = 10 * log10( 696320 / MSEQAM)
470*4882a593Smuzhiyun *
471*4882a593Smuzhiyun * We re-write the snr equation as:
472*4882a593Smuzhiyun * SNR * 2^24 = 10*(c - intlog10(MSE))
473*4882a593Smuzhiyun * Where for 256-QAM, c = log10(696320) * 2^24, and so on.
474*4882a593Smuzhiyun */
calculate_snr(u32 mse,u32 c)475*4882a593Smuzhiyun static u32 calculate_snr(u32 mse, u32 c)
476*4882a593Smuzhiyun {
477*4882a593Smuzhiyun if (mse == 0) /* No signal */
478*4882a593Smuzhiyun return 0;
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun mse = intlog10(mse);
481*4882a593Smuzhiyun if (mse > c) {
482*4882a593Smuzhiyun /*
483*4882a593Smuzhiyun * Negative SNR, which is possible, but realisticly the
484*4882a593Smuzhiyun * demod will lose lock before the signal gets this bad.
485*4882a593Smuzhiyun * The API only allows for unsigned values, so just return 0
486*4882a593Smuzhiyun */
487*4882a593Smuzhiyun return 0;
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun return 10 * (c - mse);
490*4882a593Smuzhiyun }
491*4882a593Smuzhiyun
lgdt3302_read_snr(struct dvb_frontend * fe)492*4882a593Smuzhiyun static int lgdt3302_read_snr(struct dvb_frontend *fe)
493*4882a593Smuzhiyun {
494*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
495*4882a593Smuzhiyun u8 buf[5]; /* read data buffer */
496*4882a593Smuzhiyun u32 noise; /* noise value */
497*4882a593Smuzhiyun u32 c; /* per-modulation SNR calculation constant */
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun switch (state->current_modulation) {
500*4882a593Smuzhiyun case VSB_8:
501*4882a593Smuzhiyun i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf, 5);
502*4882a593Smuzhiyun #ifdef USE_EQMSE
503*4882a593Smuzhiyun /* Use Equalizer Mean-Square Error Register */
504*4882a593Smuzhiyun /* SNR for ranges from -15.61 to +41.58 */
505*4882a593Smuzhiyun noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
506*4882a593Smuzhiyun c = 69765745; /* log10(25*24^2)*2^24 */
507*4882a593Smuzhiyun #else
508*4882a593Smuzhiyun /* Use Phase Tracker Mean-Square Error Register */
509*4882a593Smuzhiyun /* SNR for ranges from -13.11 to +44.08 */
510*4882a593Smuzhiyun noise = ((buf[0] & 7 << 3) << 13) | (buf[3] << 8) | buf[4];
511*4882a593Smuzhiyun c = 73957994; /* log10(25*32^2)*2^24 */
512*4882a593Smuzhiyun #endif
513*4882a593Smuzhiyun break;
514*4882a593Smuzhiyun case QAM_64:
515*4882a593Smuzhiyun case QAM_256:
516*4882a593Smuzhiyun i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
517*4882a593Smuzhiyun noise = ((buf[0] & 3) << 8) | buf[1];
518*4882a593Smuzhiyun c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
519*4882a593Smuzhiyun /* log10(688128)*2^24 and log10(696320)*2^24 */
520*4882a593Smuzhiyun break;
521*4882a593Smuzhiyun default:
522*4882a593Smuzhiyun dev_err(&state->client->dev,
523*4882a593Smuzhiyun "%s: Modulation set to unsupported value\n",
524*4882a593Smuzhiyun __func__);
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun state->snr = 0;
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun state->snr = calculate_snr(noise, c);
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun dprintk(state, "noise = 0x%08x, snr = %d.%02d dB\n", noise,
534*4882a593Smuzhiyun state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun return 0;
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun
lgdt3303_read_snr(struct dvb_frontend * fe)539*4882a593Smuzhiyun static int lgdt3303_read_snr(struct dvb_frontend *fe)
540*4882a593Smuzhiyun {
541*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
542*4882a593Smuzhiyun u8 buf[5]; /* read data buffer */
543*4882a593Smuzhiyun u32 noise; /* noise value */
544*4882a593Smuzhiyun u32 c; /* per-modulation SNR calculation constant */
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun switch (state->current_modulation) {
547*4882a593Smuzhiyun case VSB_8:
548*4882a593Smuzhiyun i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf, 5);
549*4882a593Smuzhiyun #ifdef USE_EQMSE
550*4882a593Smuzhiyun /* Use Equalizer Mean-Square Error Register */
551*4882a593Smuzhiyun /* SNR for ranges from -16.12 to +44.08 */
552*4882a593Smuzhiyun noise = ((buf[0] & 0x78) << 13) | (buf[1] << 8) | buf[2];
553*4882a593Smuzhiyun c = 73957994; /* log10(25*32^2)*2^24 */
554*4882a593Smuzhiyun #else
555*4882a593Smuzhiyun /* Use Phase Tracker Mean-Square Error Register */
556*4882a593Smuzhiyun /* SNR for ranges from -13.11 to +44.08 */
557*4882a593Smuzhiyun noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
558*4882a593Smuzhiyun c = 73957994; /* log10(25*32^2)*2^24 */
559*4882a593Smuzhiyun #endif
560*4882a593Smuzhiyun break;
561*4882a593Smuzhiyun case QAM_64:
562*4882a593Smuzhiyun case QAM_256:
563*4882a593Smuzhiyun i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
564*4882a593Smuzhiyun noise = (buf[0] << 8) | buf[1];
565*4882a593Smuzhiyun c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
566*4882a593Smuzhiyun /* log10(688128)*2^24 and log10(696320)*2^24 */
567*4882a593Smuzhiyun break;
568*4882a593Smuzhiyun default:
569*4882a593Smuzhiyun dev_err(&state->client->dev,
570*4882a593Smuzhiyun "%s: Modulation set to unsupported value\n",
571*4882a593Smuzhiyun __func__);
572*4882a593Smuzhiyun state->snr = 0;
573*4882a593Smuzhiyun return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
574*4882a593Smuzhiyun }
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun state->snr = calculate_snr(noise, c);
577*4882a593Smuzhiyun
578*4882a593Smuzhiyun dprintk(state, "noise = 0x%08x, snr = %d.%02d dB\n", noise,
579*4882a593Smuzhiyun state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun return 0;
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun
lgdt330x_read_snr(struct dvb_frontend * fe,u16 * snr)584*4882a593Smuzhiyun static int lgdt330x_read_snr(struct dvb_frontend *fe, u16 *snr)
585*4882a593Smuzhiyun {
586*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun return 0;
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun
lgdt330x_read_signal_strength(struct dvb_frontend * fe,u16 * strength)593*4882a593Smuzhiyun static int lgdt330x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
594*4882a593Smuzhiyun {
595*4882a593Smuzhiyun /* Calculate Strength from SNR up to 35dB */
596*4882a593Smuzhiyun /*
597*4882a593Smuzhiyun * Even though the SNR can go higher than 35dB, there is some comfort
598*4882a593Smuzhiyun * factor in having a range of strong signals that can show at 100%
599*4882a593Smuzhiyun */
600*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
601*4882a593Smuzhiyun u16 snr;
602*4882a593Smuzhiyun int ret;
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun ret = fe->ops.read_snr(fe, &snr);
605*4882a593Smuzhiyun if (ret != 0)
606*4882a593Smuzhiyun return ret;
607*4882a593Smuzhiyun /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
608*4882a593Smuzhiyun /* scale the range 0 - 35*2^24 into 0 - 65535 */
609*4882a593Smuzhiyun if (state->snr >= 8960 * 0x10000)
610*4882a593Smuzhiyun *strength = 0xffff;
611*4882a593Smuzhiyun else
612*4882a593Smuzhiyun *strength = state->snr / 8960;
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun return 0;
615*4882a593Smuzhiyun }
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun
lgdt3302_read_status(struct dvb_frontend * fe,enum fe_status * status)618*4882a593Smuzhiyun static int lgdt3302_read_status(struct dvb_frontend *fe,
619*4882a593Smuzhiyun enum fe_status *status)
620*4882a593Smuzhiyun {
621*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
622*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
623*4882a593Smuzhiyun u8 buf[3];
624*4882a593Smuzhiyun int err;
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun *status = 0; /* Reset status result */
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun /* AGC status register */
629*4882a593Smuzhiyun i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
630*4882a593Smuzhiyun dprintk(state, "AGC_STATUS = 0x%02x\n", buf[0]);
631*4882a593Smuzhiyun if ((buf[0] & 0x0c) == 0x8) {
632*4882a593Smuzhiyun /*
633*4882a593Smuzhiyun * Test signal does not exist flag
634*4882a593Smuzhiyun * as well as the AGC lock flag.
635*4882a593Smuzhiyun */
636*4882a593Smuzhiyun *status |= FE_HAS_SIGNAL;
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun /*
640*4882a593Smuzhiyun * You must set the Mask bits to 1 in the IRQ_MASK in order
641*4882a593Smuzhiyun * to see that status bit in the IRQ_STATUS register.
642*4882a593Smuzhiyun * This is done in SwReset();
643*4882a593Smuzhiyun */
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun /* signal status */
646*4882a593Smuzhiyun i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
647*4882a593Smuzhiyun dprintk(state,
648*4882a593Smuzhiyun "TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n",
649*4882a593Smuzhiyun buf[0], buf[1], buf[2]);
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun /* sync status */
652*4882a593Smuzhiyun if ((buf[2] & 0x03) == 0x01)
653*4882a593Smuzhiyun *status |= FE_HAS_SYNC;
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun /* FEC error status */
656*4882a593Smuzhiyun if ((buf[2] & 0x0c) == 0x08)
657*4882a593Smuzhiyun *status |= FE_HAS_LOCK | FE_HAS_VITERBI;
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun /* Carrier Recovery Lock Status Register */
660*4882a593Smuzhiyun i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
661*4882a593Smuzhiyun dprintk(state, "CARRIER_LOCK = 0x%02x\n", buf[0]);
662*4882a593Smuzhiyun switch (state->current_modulation) {
663*4882a593Smuzhiyun case QAM_256:
664*4882a593Smuzhiyun case QAM_64:
665*4882a593Smuzhiyun /* Need to understand why there are 3 lock levels here */
666*4882a593Smuzhiyun if ((buf[0] & 0x07) == 0x07)
667*4882a593Smuzhiyun *status |= FE_HAS_CARRIER;
668*4882a593Smuzhiyun break;
669*4882a593Smuzhiyun case VSB_8:
670*4882a593Smuzhiyun if ((buf[0] & 0x80) == 0x80)
671*4882a593Smuzhiyun *status |= FE_HAS_CARRIER;
672*4882a593Smuzhiyun break;
673*4882a593Smuzhiyun default:
674*4882a593Smuzhiyun dev_warn(&state->client->dev,
675*4882a593Smuzhiyun "%s: Modulation set to unsupported value\n",
676*4882a593Smuzhiyun __func__);
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun if (!(*status & FE_HAS_LOCK)) {
680*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
681*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
682*4882a593Smuzhiyun p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
683*4882a593Smuzhiyun return 0;
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun if (state->last_stats_time &&
687*4882a593Smuzhiyun time_is_after_jiffies(state->last_stats_time))
688*4882a593Smuzhiyun return 0;
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun state->last_stats_time = jiffies + msecs_to_jiffies(1000);
691*4882a593Smuzhiyun
692*4882a593Smuzhiyun err = lgdt3302_read_snr(fe);
693*4882a593Smuzhiyun if (!err) {
694*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
695*4882a593Smuzhiyun p->cnr.stat[0].svalue = (((u64)state->snr) * 1000) >> 24;
696*4882a593Smuzhiyun } else {
697*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
698*4882a593Smuzhiyun }
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
701*4882a593Smuzhiyun buf, sizeof(buf));
702*4882a593Smuzhiyun if (!err) {
703*4882a593Smuzhiyun state->ucblocks = (buf[0] << 8) | buf[1];
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun dprintk(state, "UCB = 0x%02x\n", state->ucblocks);
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun p->block_error.stat[0].uvalue += state->ucblocks;
708*4882a593Smuzhiyun /* FIXME: what's the basis for block count */
709*4882a593Smuzhiyun p->block_count.stat[0].uvalue += 10000;
710*4882a593Smuzhiyun
711*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_COUNTER;
712*4882a593Smuzhiyun p->block_count.stat[0].scale = FE_SCALE_COUNTER;
713*4882a593Smuzhiyun } else {
714*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
715*4882a593Smuzhiyun p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
716*4882a593Smuzhiyun }
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun return 0;
719*4882a593Smuzhiyun }
720*4882a593Smuzhiyun
lgdt3303_read_status(struct dvb_frontend * fe,enum fe_status * status)721*4882a593Smuzhiyun static int lgdt3303_read_status(struct dvb_frontend *fe,
722*4882a593Smuzhiyun enum fe_status *status)
723*4882a593Smuzhiyun {
724*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
725*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
726*4882a593Smuzhiyun u8 buf[3];
727*4882a593Smuzhiyun int err;
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun *status = 0; /* Reset status result */
730*4882a593Smuzhiyun
731*4882a593Smuzhiyun /* lgdt3303 AGC status register */
732*4882a593Smuzhiyun err = i2c_read_demod_bytes(state, 0x58, buf, 1);
733*4882a593Smuzhiyun if (err < 0)
734*4882a593Smuzhiyun return err;
735*4882a593Smuzhiyun
736*4882a593Smuzhiyun dprintk(state, "AGC_STATUS = 0x%02x\n", buf[0]);
737*4882a593Smuzhiyun if ((buf[0] & 0x21) == 0x01) {
738*4882a593Smuzhiyun /*
739*4882a593Smuzhiyun * Test input signal does not exist flag
740*4882a593Smuzhiyun * as well as the AGC lock flag.
741*4882a593Smuzhiyun */
742*4882a593Smuzhiyun *status |= FE_HAS_SIGNAL;
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun
745*4882a593Smuzhiyun /* Carrier Recovery Lock Status Register */
746*4882a593Smuzhiyun i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
747*4882a593Smuzhiyun dprintk(state, "CARRIER_LOCK = 0x%02x\n", buf[0]);
748*4882a593Smuzhiyun switch (state->current_modulation) {
749*4882a593Smuzhiyun case QAM_256:
750*4882a593Smuzhiyun case QAM_64:
751*4882a593Smuzhiyun /* Need to understand why there are 3 lock levels here */
752*4882a593Smuzhiyun if ((buf[0] & 0x07) == 0x07)
753*4882a593Smuzhiyun *status |= FE_HAS_CARRIER;
754*4882a593Smuzhiyun else
755*4882a593Smuzhiyun break;
756*4882a593Smuzhiyun i2c_read_demod_bytes(state, 0x8a, buf, 1);
757*4882a593Smuzhiyun dprintk(state, "QAM LOCK = 0x%02x\n", buf[0]);
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun if ((buf[0] & 0x04) == 0x04)
760*4882a593Smuzhiyun *status |= FE_HAS_SYNC;
761*4882a593Smuzhiyun if ((buf[0] & 0x01) == 0x01)
762*4882a593Smuzhiyun *status |= FE_HAS_LOCK;
763*4882a593Smuzhiyun if ((buf[0] & 0x08) == 0x08)
764*4882a593Smuzhiyun *status |= FE_HAS_VITERBI;
765*4882a593Smuzhiyun break;
766*4882a593Smuzhiyun case VSB_8:
767*4882a593Smuzhiyun if ((buf[0] & 0x80) == 0x80)
768*4882a593Smuzhiyun *status |= FE_HAS_CARRIER;
769*4882a593Smuzhiyun else
770*4882a593Smuzhiyun break;
771*4882a593Smuzhiyun i2c_read_demod_bytes(state, 0x38, buf, 1);
772*4882a593Smuzhiyun dprintk(state, "8-VSB LOCK = 0x%02x\n", buf[0]);
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun if ((buf[0] & 0x02) == 0x00)
775*4882a593Smuzhiyun *status |= FE_HAS_SYNC;
776*4882a593Smuzhiyun if ((buf[0] & 0x01) == 0x01)
777*4882a593Smuzhiyun *status |= FE_HAS_VITERBI | FE_HAS_LOCK;
778*4882a593Smuzhiyun break;
779*4882a593Smuzhiyun default:
780*4882a593Smuzhiyun dev_warn(&state->client->dev,
781*4882a593Smuzhiyun "%s: Modulation set to unsupported value\n",
782*4882a593Smuzhiyun __func__);
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun if (!(*status & FE_HAS_LOCK)) {
786*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
787*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
788*4882a593Smuzhiyun p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
789*4882a593Smuzhiyun return 0;
790*4882a593Smuzhiyun }
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun if (state->last_stats_time &&
793*4882a593Smuzhiyun time_is_after_jiffies(state->last_stats_time))
794*4882a593Smuzhiyun return 0;
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun state->last_stats_time = jiffies + msecs_to_jiffies(1000);
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun err = lgdt3303_read_snr(fe);
799*4882a593Smuzhiyun if (!err) {
800*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
801*4882a593Smuzhiyun p->cnr.stat[0].svalue = (((u64)state->snr) * 1000) >> 24;
802*4882a593Smuzhiyun } else {
803*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
807*4882a593Smuzhiyun buf, sizeof(buf));
808*4882a593Smuzhiyun if (!err) {
809*4882a593Smuzhiyun state->ucblocks = (buf[0] << 8) | buf[1];
810*4882a593Smuzhiyun
811*4882a593Smuzhiyun dprintk(state, "UCB = 0x%02x\n", state->ucblocks);
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun p->block_error.stat[0].uvalue += state->ucblocks;
814*4882a593Smuzhiyun /* FIXME: what's the basis for block count */
815*4882a593Smuzhiyun p->block_count.stat[0].uvalue += 10000;
816*4882a593Smuzhiyun
817*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_COUNTER;
818*4882a593Smuzhiyun p->block_count.stat[0].scale = FE_SCALE_COUNTER;
819*4882a593Smuzhiyun } else {
820*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
821*4882a593Smuzhiyun p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
822*4882a593Smuzhiyun }
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun return 0;
825*4882a593Smuzhiyun }
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun static int
lgdt330x_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * fe_tune_settings)828*4882a593Smuzhiyun lgdt330x_get_tune_settings(struct dvb_frontend *fe,
829*4882a593Smuzhiyun struct dvb_frontend_tune_settings *fe_tune_settings)
830*4882a593Smuzhiyun {
831*4882a593Smuzhiyun /* I have no idea about this - it may not be needed */
832*4882a593Smuzhiyun fe_tune_settings->min_delay_ms = 500;
833*4882a593Smuzhiyun fe_tune_settings->step_size = 0;
834*4882a593Smuzhiyun fe_tune_settings->max_drift = 0;
835*4882a593Smuzhiyun return 0;
836*4882a593Smuzhiyun }
837*4882a593Smuzhiyun
lgdt330x_release(struct dvb_frontend * fe)838*4882a593Smuzhiyun static void lgdt330x_release(struct dvb_frontend *fe)
839*4882a593Smuzhiyun {
840*4882a593Smuzhiyun struct lgdt330x_state *state = fe->demodulator_priv;
841*4882a593Smuzhiyun struct i2c_client *client = state->client;
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun dev_dbg(&client->dev, "\n");
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun i2c_unregister_device(client);
846*4882a593Smuzhiyun }
847*4882a593Smuzhiyun
lgdt330x_get_dvb_frontend(struct i2c_client * client)848*4882a593Smuzhiyun static struct dvb_frontend *lgdt330x_get_dvb_frontend(struct i2c_client *client)
849*4882a593Smuzhiyun {
850*4882a593Smuzhiyun struct lgdt330x_state *state = i2c_get_clientdata(client);
851*4882a593Smuzhiyun
852*4882a593Smuzhiyun dev_dbg(&client->dev, "\n");
853*4882a593Smuzhiyun
854*4882a593Smuzhiyun return &state->frontend;
855*4882a593Smuzhiyun }
856*4882a593Smuzhiyun
857*4882a593Smuzhiyun static const struct dvb_frontend_ops lgdt3302_ops;
858*4882a593Smuzhiyun static const struct dvb_frontend_ops lgdt3303_ops;
859*4882a593Smuzhiyun
lgdt330x_probe(struct i2c_client * client,const struct i2c_device_id * id)860*4882a593Smuzhiyun static int lgdt330x_probe(struct i2c_client *client,
861*4882a593Smuzhiyun const struct i2c_device_id *id)
862*4882a593Smuzhiyun {
863*4882a593Smuzhiyun struct lgdt330x_state *state = NULL;
864*4882a593Smuzhiyun u8 buf[1];
865*4882a593Smuzhiyun
866*4882a593Smuzhiyun /* Allocate memory for the internal state */
867*4882a593Smuzhiyun state = kzalloc(sizeof(*state), GFP_KERNEL);
868*4882a593Smuzhiyun if (!state)
869*4882a593Smuzhiyun goto error;
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun /* Setup the state */
872*4882a593Smuzhiyun memcpy(&state->config, client->dev.platform_data,
873*4882a593Smuzhiyun sizeof(state->config));
874*4882a593Smuzhiyun i2c_set_clientdata(client, state);
875*4882a593Smuzhiyun state->client = client;
876*4882a593Smuzhiyun
877*4882a593Smuzhiyun /* Create dvb_frontend */
878*4882a593Smuzhiyun switch (state->config.demod_chip) {
879*4882a593Smuzhiyun case LGDT3302:
880*4882a593Smuzhiyun memcpy(&state->frontend.ops, &lgdt3302_ops,
881*4882a593Smuzhiyun sizeof(struct dvb_frontend_ops));
882*4882a593Smuzhiyun break;
883*4882a593Smuzhiyun case LGDT3303:
884*4882a593Smuzhiyun memcpy(&state->frontend.ops, &lgdt3303_ops,
885*4882a593Smuzhiyun sizeof(struct dvb_frontend_ops));
886*4882a593Smuzhiyun break;
887*4882a593Smuzhiyun default:
888*4882a593Smuzhiyun goto error;
889*4882a593Smuzhiyun }
890*4882a593Smuzhiyun state->frontend.demodulator_priv = state;
891*4882a593Smuzhiyun
892*4882a593Smuzhiyun /* Setup get frontend callback */
893*4882a593Smuzhiyun state->config.get_dvb_frontend = lgdt330x_get_dvb_frontend;
894*4882a593Smuzhiyun
895*4882a593Smuzhiyun /* Verify communication with demod chip */
896*4882a593Smuzhiyun if (i2c_read_demod_bytes(state, 2, buf, 1))
897*4882a593Smuzhiyun goto error;
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun state->current_frequency = -1;
900*4882a593Smuzhiyun state->current_modulation = -1;
901*4882a593Smuzhiyun
902*4882a593Smuzhiyun dev_info(&state->client->dev,
903*4882a593Smuzhiyun "Demod loaded for LGDT330%s chip\n",
904*4882a593Smuzhiyun state->config.demod_chip == LGDT3302 ? "2" : "3");
905*4882a593Smuzhiyun
906*4882a593Smuzhiyun return 0;
907*4882a593Smuzhiyun
908*4882a593Smuzhiyun error:
909*4882a593Smuzhiyun kfree(state);
910*4882a593Smuzhiyun if (debug)
911*4882a593Smuzhiyun dev_printk(KERN_DEBUG, &client->dev, "Error loading lgdt330x driver\n");
912*4882a593Smuzhiyun return -ENODEV;
913*4882a593Smuzhiyun }
lgdt330x_attach(const struct lgdt330x_config * _config,u8 demod_address,struct i2c_adapter * i2c)914*4882a593Smuzhiyun struct dvb_frontend *lgdt330x_attach(const struct lgdt330x_config *_config,
915*4882a593Smuzhiyun u8 demod_address,
916*4882a593Smuzhiyun struct i2c_adapter *i2c)
917*4882a593Smuzhiyun {
918*4882a593Smuzhiyun struct i2c_client *client;
919*4882a593Smuzhiyun struct i2c_board_info board_info = {};
920*4882a593Smuzhiyun struct lgdt330x_config config = *_config;
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun strscpy(board_info.type, "lgdt330x", sizeof(board_info.type));
923*4882a593Smuzhiyun board_info.addr = demod_address;
924*4882a593Smuzhiyun board_info.platform_data = &config;
925*4882a593Smuzhiyun client = i2c_new_client_device(i2c, &board_info);
926*4882a593Smuzhiyun if (!i2c_client_has_driver(client))
927*4882a593Smuzhiyun return NULL;
928*4882a593Smuzhiyun
929*4882a593Smuzhiyun return lgdt330x_get_dvb_frontend(client);
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun EXPORT_SYMBOL(lgdt330x_attach);
932*4882a593Smuzhiyun
933*4882a593Smuzhiyun static const struct dvb_frontend_ops lgdt3302_ops = {
934*4882a593Smuzhiyun .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
935*4882a593Smuzhiyun .info = {
936*4882a593Smuzhiyun .name = "LG Electronics LGDT3302 VSB/QAM Frontend",
937*4882a593Smuzhiyun .frequency_min_hz = 54 * MHz,
938*4882a593Smuzhiyun .frequency_max_hz = 858 * MHz,
939*4882a593Smuzhiyun .frequency_stepsize_hz = 62500,
940*4882a593Smuzhiyun .symbol_rate_min = 5056941, /* QAM 64 */
941*4882a593Smuzhiyun .symbol_rate_max = 10762000, /* VSB 8 */
942*4882a593Smuzhiyun .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
943*4882a593Smuzhiyun },
944*4882a593Smuzhiyun .init = lgdt330x_init,
945*4882a593Smuzhiyun .set_frontend = lgdt330x_set_parameters,
946*4882a593Smuzhiyun .get_frontend = lgdt330x_get_frontend,
947*4882a593Smuzhiyun .get_tune_settings = lgdt330x_get_tune_settings,
948*4882a593Smuzhiyun .read_status = lgdt3302_read_status,
949*4882a593Smuzhiyun .read_signal_strength = lgdt330x_read_signal_strength,
950*4882a593Smuzhiyun .read_snr = lgdt330x_read_snr,
951*4882a593Smuzhiyun .read_ucblocks = lgdt330x_read_ucblocks,
952*4882a593Smuzhiyun .release = lgdt330x_release,
953*4882a593Smuzhiyun };
954*4882a593Smuzhiyun
955*4882a593Smuzhiyun static const struct dvb_frontend_ops lgdt3303_ops = {
956*4882a593Smuzhiyun .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
957*4882a593Smuzhiyun .info = {
958*4882a593Smuzhiyun .name = "LG Electronics LGDT3303 VSB/QAM Frontend",
959*4882a593Smuzhiyun .frequency_min_hz = 54 * MHz,
960*4882a593Smuzhiyun .frequency_max_hz = 858 * MHz,
961*4882a593Smuzhiyun .frequency_stepsize_hz = 62500,
962*4882a593Smuzhiyun .symbol_rate_min = 5056941, /* QAM 64 */
963*4882a593Smuzhiyun .symbol_rate_max = 10762000, /* VSB 8 */
964*4882a593Smuzhiyun .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
965*4882a593Smuzhiyun },
966*4882a593Smuzhiyun .init = lgdt330x_init,
967*4882a593Smuzhiyun .set_frontend = lgdt330x_set_parameters,
968*4882a593Smuzhiyun .get_frontend = lgdt330x_get_frontend,
969*4882a593Smuzhiyun .get_tune_settings = lgdt330x_get_tune_settings,
970*4882a593Smuzhiyun .read_status = lgdt3303_read_status,
971*4882a593Smuzhiyun .read_signal_strength = lgdt330x_read_signal_strength,
972*4882a593Smuzhiyun .read_snr = lgdt330x_read_snr,
973*4882a593Smuzhiyun .read_ucblocks = lgdt330x_read_ucblocks,
974*4882a593Smuzhiyun .release = lgdt330x_release,
975*4882a593Smuzhiyun };
976*4882a593Smuzhiyun
lgdt330x_remove(struct i2c_client * client)977*4882a593Smuzhiyun static int lgdt330x_remove(struct i2c_client *client)
978*4882a593Smuzhiyun {
979*4882a593Smuzhiyun struct lgdt330x_state *state = i2c_get_clientdata(client);
980*4882a593Smuzhiyun
981*4882a593Smuzhiyun dev_dbg(&client->dev, "\n");
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun kfree(state);
984*4882a593Smuzhiyun
985*4882a593Smuzhiyun return 0;
986*4882a593Smuzhiyun }
987*4882a593Smuzhiyun
988*4882a593Smuzhiyun static const struct i2c_device_id lgdt330x_id_table[] = {
989*4882a593Smuzhiyun {"lgdt330x", 0},
990*4882a593Smuzhiyun {}
991*4882a593Smuzhiyun };
992*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, lgdt330x_id_table);
993*4882a593Smuzhiyun
994*4882a593Smuzhiyun static struct i2c_driver lgdt330x_driver = {
995*4882a593Smuzhiyun .driver = {
996*4882a593Smuzhiyun .name = "lgdt330x",
997*4882a593Smuzhiyun .suppress_bind_attrs = true,
998*4882a593Smuzhiyun },
999*4882a593Smuzhiyun .probe = lgdt330x_probe,
1000*4882a593Smuzhiyun .remove = lgdt330x_remove,
1001*4882a593Smuzhiyun .id_table = lgdt330x_id_table,
1002*4882a593Smuzhiyun };
1003*4882a593Smuzhiyun
1004*4882a593Smuzhiyun module_i2c_driver(lgdt330x_driver);
1005*4882a593Smuzhiyun
1006*4882a593Smuzhiyun
1007*4882a593Smuzhiyun MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
1008*4882a593Smuzhiyun MODULE_AUTHOR("Wilson Michaels");
1009*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1010