aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r--drivers/media/dvb/frontends/Kconfig4
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c27
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h1
-rw-r--r--drivers/media/dvb/frontends/lgdt3302.c599
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c831
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h (renamed from drivers/media/dvb/frontends/lgdt3302.h)32
-rw-r--r--drivers/media/dvb/frontends/lgdt330x_priv.h (renamed from drivers/media/dvb/frontends/lgdt3302_priv.h)16
8 files changed, 887 insertions, 625 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index d847c62bd837..e83256d0fd14 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -187,8 +187,8 @@ config DVB_BCM3510
187 An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to 187 An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
188 support this frontend. 188 support this frontend.
189 189
190config DVB_LGDT3302 190config DVB_LGDT330X
191 tristate "LGDT3302 based (DViCO FusionHDTV3 Gold)" 191 tristate "LGDT3302 or LGDT3303 based (DViCO FusionHDTV Gold)"
192 depends on DVB_CORE 192 depends on DVB_CORE
193 help 193 help
194 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 194 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index de5e240cba7f..ad8658ffd60a 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -30,4 +30,4 @@ obj-$(CONFIG_DVB_OR51211) += or51211.o
30obj-$(CONFIG_DVB_OR51132) += or51132.o 30obj-$(CONFIG_DVB_OR51132) += or51132.o
31obj-$(CONFIG_DVB_BCM3510) += bcm3510.o 31obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
32obj-$(CONFIG_DVB_S5H1420) += s5h1420.o 32obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
33obj-$(CONFIG_DVB_LGDT3302) += lgdt3302.o 33obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 5afeaa9b43b4..536c35d969b7 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -82,13 +82,14 @@ struct dvb_pll_desc dvb_pll_lg_z201 = {
82 .name = "LG z201", 82 .name = "LG z201",
83 .min = 174000000, 83 .min = 174000000,
84 .max = 862000000, 84 .max = 862000000,
85 .count = 5, 85 .count = 6,
86 .entries = { 86 .entries = {
87 { 0, 36166667, 166666, 0xbc, 0x03 }, 87 { 0, 36166667, 166666, 0xbc, 0x03 },
88 { 443250000, 36166667, 166666, 0xbc, 0x01 }, 88 { 157500000, 36166667, 166666, 0xbc, 0x01 },
89 { 542000000, 36166667, 166666, 0xbc, 0x02 }, 89 { 443250000, 36166667, 166666, 0xbc, 0x02 },
90 { 830000000, 36166667, 166666, 0xf4, 0x02 }, 90 { 542000000, 36166667, 166666, 0xbc, 0x04 },
91 { 999999999, 36166667, 166666, 0xfc, 0x02 }, 91 { 830000000, 36166667, 166666, 0xf4, 0x04 },
92 { 999999999, 36166667, 166666, 0xfc, 0x04 },
92 }, 93 },
93}; 94};
94EXPORT_SYMBOL(dvb_pll_lg_z201); 95EXPORT_SYMBOL(dvb_pll_lg_z201);
@@ -224,6 +225,22 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
224}; 225};
225EXPORT_SYMBOL(dvb_pll_tua6034); 226EXPORT_SYMBOL(dvb_pll_tua6034);
226 227
228/* Infineon TUA6034
229 * used in LG Innotek TDVS-H062F
230 */
231struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
232 .name = "LG/Infineon TUA6034",
233 .min = 54000000,
234 .max = 863000000,
235 .count = 3,
236 .entries = {
237 { 160000000, 44000000, 62500, 0xce, 0x01 },
238 { 455000000, 44000000, 62500, 0xce, 0x02 },
239 { 999999999, 44000000, 62500, 0xce, 0x04 },
240 },
241};
242EXPORT_SYMBOL(dvb_pll_tdvs_tua6034);
243
227/* Philips FMD1216ME 244/* Philips FMD1216ME
228 * used in Medion Hybrid PCMCIA card and USB Box 245 * used in Medion Hybrid PCMCIA card and USB Box
229 */ 246 */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index cb794759d89e..205b2d1a8852 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -31,6 +31,7 @@ extern struct dvb_pll_desc dvb_pll_unknown_1;
31extern struct dvb_pll_desc dvb_pll_tua6010xs; 31extern struct dvb_pll_desc dvb_pll_tua6010xs;
32extern struct dvb_pll_desc dvb_pll_env57h1xd5; 32extern struct dvb_pll_desc dvb_pll_env57h1xd5;
33extern struct dvb_pll_desc dvb_pll_tua6034; 33extern struct dvb_pll_desc dvb_pll_tua6034;
34extern struct dvb_pll_desc dvb_pll_tdvs_tua6034;
34extern struct dvb_pll_desc dvb_pll_tda665x; 35extern struct dvb_pll_desc dvb_pll_tda665x;
35extern struct dvb_pll_desc dvb_pll_fmd1216me; 36extern struct dvb_pll_desc dvb_pll_fmd1216me;
36extern struct dvb_pll_desc dvb_pll_tded4; 37extern struct dvb_pll_desc dvb_pll_tded4;
diff --git a/drivers/media/dvb/frontends/lgdt3302.c b/drivers/media/dvb/frontends/lgdt3302.c
deleted file mode 100644
index c85a2a99df42..000000000000
--- a/drivers/media/dvb/frontends/lgdt3302.c
+++ /dev/null
@@ -1,599 +0,0 @@
1/*
2 * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
3 *
4 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
5 *
6 * Based on code from Kirk Lapray <kirk_lapray@bigfoot.com>
7 * Copyright (C) 2005
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25/*
26 * NOTES ABOUT THIS DRIVER
27 *
28 * This driver supports DViCO FusionHDTV 3 Gold under Linux.
29 *
30 * TODO:
31 * BER and signal strength always return 0.
32 *
33 */
34
35#include <linux/kernel.h>
36#include <linux/module.h>
37#include <linux/moduleparam.h>
38#include <linux/init.h>
39#include <linux/delay.h>
40#include <asm/byteorder.h>
41
42#include "dvb_frontend.h"
43#include "dvb-pll.h"
44#include "lgdt3302_priv.h"
45#include "lgdt3302.h"
46
47static int debug = 0;
48module_param(debug, int, 0644);
49MODULE_PARM_DESC(debug,"Turn on/off lgdt3302 frontend debugging (default:off).");
50#define dprintk(args...) \
51do { \
52if (debug) printk(KERN_DEBUG "lgdt3302: " args); \
53} while (0)
54
55struct lgdt3302_state
56{
57 struct i2c_adapter* i2c;
58 struct dvb_frontend_ops ops;
59
60 /* Configuration settings */
61 const struct lgdt3302_config* config;
62
63 struct dvb_frontend frontend;
64
65 /* Demodulator private data */
66 fe_modulation_t current_modulation;
67
68 /* Tuner private data */
69 u32 current_frequency;
70};
71
72static int i2c_writebytes (struct lgdt3302_state* state,
73 u8 addr, /* demod_address or pll_address */
74 u8 *buf, /* data bytes to send */
75 int len /* number of bytes to send */ )
76{
77 if (addr == state->config->pll_address) {
78 struct i2c_msg msg =
79 { .addr = addr, .flags = 0, .buf = buf, .len = len };
80 int err;
81
82 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
83 printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
84 if (err < 0)
85 return err;
86 else
87 return -EREMOTEIO;
88 }
89 } else {
90 u8 tmp[] = { buf[0], buf[1] };
91 struct i2c_msg msg =
92 { .addr = addr, .flags = 0, .buf = tmp, .len = 2 };
93 int err;
94 int i;
95
96 for (i=1; i<len; i++) {
97 tmp[1] = buf[i];
98 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
99 printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
100 if (err < 0)
101 return err;
102 else
103 return -EREMOTEIO;
104 }
105 tmp[0]++;
106 }
107 }
108 return 0;
109}
110static int i2c_readbytes (struct lgdt3302_state* state,
111 u8 addr, /* demod_address or pll_address */
112 u8 *buf, /* holds data bytes read */
113 int len /* number of bytes to read */ )
114{
115 struct i2c_msg msg =
116 { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
117 int err;
118
119 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
120 printk(KERN_WARNING "lgdt3302: %s error (addr %02x, err == %i)\n", __FUNCTION__, addr, err);
121 return -EREMOTEIO;
122 }
123 return 0;
124}
125
126/*
127 * This routine writes the register (reg) to the demod bus
128 * then reads the data returned for (len) bytes.
129 */
130
131static u8 i2c_selectreadbytes (struct lgdt3302_state* state,
132 enum I2C_REG reg, u8* buf, int len)
133{
134 u8 wr [] = { reg };
135 struct i2c_msg msg [] = {
136 { .addr = state->config->demod_address,
137 .flags = 0, .buf = wr, .len = 1 },
138 { .addr = state->config->demod_address,
139 .flags = I2C_M_RD, .buf = buf, .len = len },
140 };
141 int ret;
142 ret = i2c_transfer(state->i2c, msg, 2);
143 if (ret != 2) {
144 printk(KERN_WARNING "lgdt3302: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
145 } else {
146 ret = 0;
147 }
148 return ret;
149}
150
151/* Software reset */
152int lgdt3302_SwReset(struct lgdt3302_state* state)
153{
154 u8 ret;
155 u8 reset[] = {
156 IRQ_MASK,
157 0x00 /* bit 6 is active low software reset
158 * bits 5-0 are 1 to mask interrupts */
159 };
160
161 ret = i2c_writebytes(state,
162 state->config->demod_address,
163 reset, sizeof(reset));
164 if (ret == 0) {
165 /* spec says reset takes 100 ns why wait */
166 /* mdelay(100); */ /* keep low for 100mS */
167 reset[1] = 0x7f; /* force reset high (inactive)
168 * and unmask interrupts */
169 ret = i2c_writebytes(state,
170 state->config->demod_address,
171 reset, sizeof(reset));
172 }
173 /* Spec does not indicate a need for this either */
174 /*mdelay(5); */ /* wait 5 msec before doing more */
175 return ret;
176}
177
178static int lgdt3302_init(struct dvb_frontend* fe)
179{
180 /* Hardware reset is done using gpio[0] of cx23880x chip.
181 * I'd like to do it here, but don't know how to find chip address.
182 * cx88-cards.c arranges for the reset bit to be inactive (high).
183 * Maybe there needs to be a callable function in cx88-core or
184 * the caller of this function needs to do it. */
185
186 dprintk("%s entered\n", __FUNCTION__);
187 return lgdt3302_SwReset((struct lgdt3302_state*) fe->demodulator_priv);
188}
189
190static int lgdt3302_read_ber(struct dvb_frontend* fe, u32* ber)
191{
192 *ber = 0; /* Dummy out for now */
193 return 0;
194}
195
196static int lgdt3302_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
197{
198 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
199 u8 buf[2];
200
201 i2c_selectreadbytes(state, PACKET_ERR_COUNTER1, buf, sizeof(buf));
202
203 *ucblocks = (buf[0] << 8) | buf[1];
204 return 0;
205}
206
207static int lgdt3302_set_parameters(struct dvb_frontend* fe,
208 struct dvb_frontend_parameters *param)
209{
210 u8 buf[4];
211 struct lgdt3302_state* state =
212 (struct lgdt3302_state*) fe->demodulator_priv;
213
214 /* Use 50MHz parameter values from spec sheet since xtal is 50 */
215 static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
216 static u8 vsb_freq_cfg[] = { VSB_CARRIER_FREQ0, 0x00, 0x87, 0x8e, 0x01 };
217 static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };
218 static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
219 static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 };
220 static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x07, 0x00, 0xfe };
221 static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };
222
223 /* Change only if we are actually changing the modulation */
224 if (state->current_modulation != param->u.vsb.modulation) {
225 switch(param->u.vsb.modulation) {
226 case VSB_8:
227 dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
228
229 /* Select VSB mode and serial MPEG interface */
230 top_ctrl_cfg[1] = 0x07;
231 break;
232
233 case QAM_64:
234 dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
235
236 /* Select QAM_64 mode and serial MPEG interface */
237 top_ctrl_cfg[1] = 0x04;
238 break;
239
240 case QAM_256:
241 dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
242
243 /* Select QAM_256 mode and serial MPEG interface */
244 top_ctrl_cfg[1] = 0x05;
245 break;
246 default:
247 printk(KERN_WARNING "lgdt3302: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
248 return -1;
249 }
250 /* Initializations common to all modes */
251
252 /* Select the requested mode */
253 i2c_writebytes(state, state->config->demod_address,
254 top_ctrl_cfg, sizeof(top_ctrl_cfg));
255
256 /* Change the value of IFBW[11:0]
257 of AGC IF/RF loop filter bandwidth register */
258 i2c_writebytes(state, state->config->demod_address,
259 agc_rf_cfg, sizeof(agc_rf_cfg));
260
261 /* Change the value of bit 6, 'nINAGCBY' and
262 'NSSEL[1:0] of ACG function control register 2 */
263 /* Change the value of bit 6 'RFFIX'
264 of AGC function control register 3 */
265 i2c_writebytes(state, state->config->demod_address,
266 agc_ctrl_cfg, sizeof(agc_ctrl_cfg));
267
268 /* Change the TPCLK pin polarity
269 data is valid on falling clock */
270 i2c_writebytes(state, state->config->demod_address,
271 demux_ctrl_cfg, sizeof(demux_ctrl_cfg));
272
273 /* Change the value of NCOCTFV[25:0] of carrier
274 recovery center frequency register */
275 i2c_writebytes(state, state->config->demod_address,
276 vsb_freq_cfg, sizeof(vsb_freq_cfg));
277
278 /* Set the value of 'INLVTHD' register 0x2a/0x2c to 0x7fe */
279 i2c_writebytes(state, state->config->demod_address,
280 agc_delay_cfg, sizeof(agc_delay_cfg));
281
282 /* Change the value of IAGCBW[15:8]
283 of inner AGC loop filter bandwith */
284 i2c_writebytes(state, state->config->demod_address,
285 agc_loop_cfg, sizeof(agc_loop_cfg));
286
287 state->config->set_ts_params(fe, 0);
288 state->current_modulation = param->u.vsb.modulation;
289 }
290
291 /* Change only if we are actually changing the channel */
292 if (state->current_frequency != param->frequency) {
293 dvb_pll_configure(state->config->pll_desc, buf,
294 param->frequency, 0);
295 dprintk("%s: tuner bytes: 0x%02x 0x%02x "
296 "0x%02x 0x%02x\n", __FUNCTION__, buf[0],buf[1],buf[2],buf[3]);
297 i2c_writebytes(state, state->config->pll_address ,buf, 4);
298
299 /* Check the status of the tuner pll */
300 i2c_readbytes(state, state->config->pll_address, buf, 1);
301 dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
302
303 /* Update current frequency */
304 state->current_frequency = param->frequency;
305 }
306 lgdt3302_SwReset(state);
307 return 0;
308}
309
310static int lgdt3302_get_frontend(struct dvb_frontend* fe,
311 struct dvb_frontend_parameters* param)
312{
313 struct lgdt3302_state *state = fe->demodulator_priv;
314 param->frequency = state->current_frequency;
315 return 0;
316}
317
318static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
319{
320 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
321 u8 buf[3];
322
323 *status = 0; /* Reset status result */
324
325 /* Check the status of the tuner pll */
326 i2c_readbytes(state, state->config->pll_address, buf, 1);
327 dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
328 if ((buf[0] & 0xc0) != 0x40)
329 return 0; /* Tuner PLL not locked or not powered on */
330
331 /*
332 * You must set the Mask bits to 1 in the IRQ_MASK in order
333 * to see that status bit in the IRQ_STATUS register.
334 * This is done in SwReset();
335 */
336
337 /* AGC status register */
338 i2c_selectreadbytes(state, AGC_STATUS, buf, 1);
339 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
340 if ((buf[0] & 0x0c) == 0x8){
341 /* Test signal does not exist flag */
342 /* as well as the AGC lock flag. */
343 *status |= FE_HAS_SIGNAL;
344 } else {
345 /* Without a signal all other status bits are meaningless */
346 return 0;
347 }
348
349 /* signal status */
350 i2c_selectreadbytes(state, TOP_CONTROL, buf, sizeof(buf));
351 dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
352
353#if 0
354 /* Alternative method to check for a signal */
355 /* using the SNR good/bad interrupts. */
356 if ((buf[2] & 0x30) == 0x10)
357 *status |= FE_HAS_SIGNAL;
358#endif
359
360 /* sync status */
361 if ((buf[2] & 0x03) == 0x01) {
362 *status |= FE_HAS_SYNC;
363 }
364
365 /* FEC error status */
366 if ((buf[2] & 0x0c) == 0x08) {
367 *status |= FE_HAS_LOCK;
368 *status |= FE_HAS_VITERBI;
369 }
370
371 /* Carrier Recovery Lock Status Register */
372 i2c_selectreadbytes(state, CARRIER_LOCK, buf, 1);
373 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
374 switch (state->current_modulation) {
375 case QAM_256:
376 case QAM_64:
377 /* Need to undestand why there are 3 lock levels here */
378 if ((buf[0] & 0x07) == 0x07)
379 *status |= FE_HAS_CARRIER;
380 break;
381 case VSB_8:
382 if ((buf[0] & 0x80) == 0x80)
383 *status |= FE_HAS_CARRIER;
384 break;
385 default:
386 printk("KERN_WARNING lgdt3302: %s: Modulation set to unsupported value\n", __FUNCTION__);
387 }
388
389 return 0;
390}
391
392static int lgdt3302_read_signal_strength(struct dvb_frontend* fe, u16* strength)
393{
394 /* not directly available. */
395 return 0;
396}
397
398static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
399{
400#ifdef SNR_IN_DB
401 /*
402 * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
403 * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
404 * respectively. The following tables are built on these formulas.
405 * The usual definition is SNR = 20 log10(signal/noise)
406 * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
407 *
408 * This table is a an ordered list of noise values computed by the
409 * formula from the spec sheet such that the index into the table
410 * starting at 43 or 45 is the SNR value in db. There are duplicate noise
411 * value entries at the beginning because the SNR varies more than
412 * 1 db for a change of 1 digit in noise at very small values of noise.
413 *
414 * Examples from SNR_EQ table:
415 * noise SNR
416 * 0 43
417 * 1 42
418 * 2 39
419 * 3 37
420 * 4 36
421 * 5 35
422 * 6 34
423 * 7 33
424 * 8 33
425 * 9 32
426 * 10 32
427 * 11 31
428 * 12 31
429 * 13 30
430 */
431
432 static const u32 SNR_EQ[] =
433 { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7,
434 9, 11, 13, 17, 21, 26, 33, 41, 52, 65,
435 81, 102, 129, 162, 204, 257, 323, 406, 511, 644,
436 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433,
437 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323,
438 80978, 101945, 128341, 161571, 203406, 256073, 0x40000
439 };
440
441 static const u32 SNR_PH[] =
442 { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8,
443 10, 12, 15, 19, 23, 29, 37, 46, 58, 73,
444 91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
445 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
446 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
447 90833, 114351, 143960, 181235, 228161, 0x040000
448 };
449
450 static u8 buf[5];/* read data buffer */
451 static u32 noise; /* noise value */
452 static u32 snr_db; /* index into SNR_EQ[] */
453 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
454
455 /* read both equalizer and pase tracker noise data */
456 i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
457
458 if (state->current_modulation == VSB_8) {
459 /* Equalizer Mean-Square Error Register for VSB */
460 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
461
462 /*
463 * Look up noise value in table.
464 * A better search algorithm could be used...
465 * watch out there are duplicate entries.
466 */
467 for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
468 if (noise < SNR_EQ[snr_db]) {
469 *snr = 43 - snr_db;
470 break;
471 }
472 }
473 } else {
474 /* Phase Tracker Mean-Square Error Register for QAM */
475 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
476
477 /* Look up noise value in table. */
478 for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
479 if (noise < SNR_PH[snr_db]) {
480 *snr = 45 - snr_db;
481 break;
482 }
483 }
484 }
485#else
486 /* Return the raw noise value */
487 static u8 buf[5];/* read data buffer */
488 static u32 noise; /* noise value */
489 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
490
491 /* read both equalizer and pase tracker noise data */
492 i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
493
494 if (state->current_modulation == VSB_8) {
495 /* Equalizer Mean-Square Error Register for VSB */
496 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
497 } else {
498 /* Phase Tracker Mean-Square Error Register for QAM */
499 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
500 }
501
502 /* Small values for noise mean signal is better so invert noise */
503 /* Noise is 19 bit value so discard 3 LSB*/
504 *snr = ~noise>>3;
505#endif
506
507 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
508
509 return 0;
510}
511
512static int lgdt3302_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
513{
514 /* I have no idea about this - it may not be needed */
515 fe_tune_settings->min_delay_ms = 500;
516 fe_tune_settings->step_size = 0;
517 fe_tune_settings->max_drift = 0;
518 return 0;
519}
520
521static void lgdt3302_release(struct dvb_frontend* fe)
522{
523 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
524 kfree(state);
525}
526
527static struct dvb_frontend_ops lgdt3302_ops;
528
529struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config,
530 struct i2c_adapter* i2c)
531{
532 struct lgdt3302_state* state = NULL;
533 u8 buf[1];
534
535 /* Allocate memory for the internal state */
536 state = (struct lgdt3302_state*) kmalloc(sizeof(struct lgdt3302_state), GFP_KERNEL);
537 if (state == NULL)
538 goto error;
539 memset(state,0,sizeof(*state));
540
541 /* Setup the state */
542 state->config = config;
543 state->i2c = i2c;
544 memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
545 /* Verify communication with demod chip */
546 if (i2c_selectreadbytes(state, 2, buf, 1))
547 goto error;
548
549 state->current_frequency = -1;
550 state->current_modulation = -1;
551
552 /* Create dvb_frontend */
553 state->frontend.ops = &state->ops;
554 state->frontend.demodulator_priv = state;
555 return &state->frontend;
556
557error:
558 if (state)
559 kfree(state);
560 dprintk("%s: ERROR\n",__FUNCTION__);
561 return NULL;
562}
563
564static struct dvb_frontend_ops lgdt3302_ops = {
565 .info = {
566 .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
567 .type = FE_ATSC,
568 .frequency_min= 54000000,
569 .frequency_max= 858000000,
570 .frequency_stepsize= 62500,
571 /* Symbol rate is for all VSB modes need to check QAM */
572 .symbol_rate_min = 10762000,
573 .symbol_rate_max = 10762000,
574 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
575 },
576 .init = lgdt3302_init,
577 .set_frontend = lgdt3302_set_parameters,
578 .get_frontend = lgdt3302_get_frontend,
579 .get_tune_settings = lgdt3302_get_tune_settings,
580 .read_status = lgdt3302_read_status,
581 .read_ber = lgdt3302_read_ber,
582 .read_signal_strength = lgdt3302_read_signal_strength,
583 .read_snr = lgdt3302_read_snr,
584 .read_ucblocks = lgdt3302_read_ucblocks,
585 .release = lgdt3302_release,
586};
587
588MODULE_DESCRIPTION("LGDT3302 [DViCO FusionHDTV 3 Gold] (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
589MODULE_AUTHOR("Wilson Michaels");
590MODULE_LICENSE("GPL");
591
592EXPORT_SYMBOL(lgdt3302_attach);
593
594/*
595 * Local variables:
596 * c-basic-offset: 8
597 * compile-command: "make DVB=1"
598 * End:
599 */
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
new file mode 100644
index 000000000000..c48e7c11d708
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -0,0 +1,831 @@
1/*
2 * Support for LGDT3302 and LGDT3303 - VSB/QAM
3 *
4 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22/*
23 * NOTES ABOUT THIS DRIVER
24 *
25 * This Linux driver supports:
26 * DViCO FusionHDTV 3 Gold-Q
27 * DViCO FusionHDTV 3 Gold-T
28 * DViCO FusionHDTV 5 Gold
29 *
30 * TODO:
31 * signal strength always returns 0.
32 *
33 */
34
35#include <linux/kernel.h>
36#include <linux/module.h>
37#include <linux/moduleparam.h>
38#include <linux/init.h>
39#include <linux/delay.h>
40#include <asm/byteorder.h>
41
42#include "dvb_frontend.h"
43#include "lgdt330x_priv.h"
44#include "lgdt330x.h"
45
46static int debug = 0;
47module_param(debug, int, 0644);
48MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off).");
49#define dprintk(args...) \
50do { \
51if (debug) printk(KERN_DEBUG "lgdt330x: " args); \
52} while (0)
53
54struct lgdt330x_state
55{
56 struct i2c_adapter* i2c;
57 struct dvb_frontend_ops ops;
58
59 /* Configuration settings */
60 const struct lgdt330x_config* config;
61
62 struct dvb_frontend frontend;
63
64 /* Demodulator private data */
65 fe_modulation_t current_modulation;
66
67 /* Tuner private data */
68 u32 current_frequency;
69};
70
71static int i2c_write_demod_bytes (struct lgdt330x_state* state,
72 u8 *buf, /* data bytes to send */
73 int len /* number of bytes to send */ )
74{
75 struct i2c_msg msg =
76 { .addr = state->config->demod_address,
77 .flags = 0,
78 .buf = buf,
79 .len = 2 };
80 int i;
81 int err;
82
83 for (i=0; i<len-1; i+=2){
84 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
85 printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, msg.buf[0], msg.buf[1], err);
86 if (err < 0)
87 return err;
88 else
89 return -EREMOTEIO;
90 }
91 msg.buf += 2;
92 }
93 return 0;
94}
95
96/*
97 * This routine writes the register (reg) to the demod bus
98 * then reads the data returned for (len) bytes.
99 */
100
101static u8 i2c_read_demod_bytes (struct lgdt330x_state* state,
102 enum I2C_REG reg, u8* buf, int len)
103{
104 u8 wr [] = { reg };
105 struct i2c_msg msg [] = {
106 { .addr = state->config->demod_address,
107 .flags = 0, .buf = wr, .len = 1 },
108 { .addr = state->config->demod_address,
109 .flags = I2C_M_RD, .buf = buf, .len = len },
110 };
111 int ret;
112 ret = i2c_transfer(state->i2c, msg, 2);
113 if (ret != 2) {
114 printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
115 } else {
116 ret = 0;
117 }
118 return ret;
119}
120
121/* Software reset */
122static int lgdt3302_SwReset(struct lgdt330x_state* state)
123{
124 u8 ret;
125 u8 reset[] = {
126 IRQ_MASK,
127 0x00 /* bit 6 is active low software reset
128 * bits 5-0 are 1 to mask interrupts */
129 };
130
131 ret = i2c_write_demod_bytes(state,
132 reset, sizeof(reset));
133 if (ret == 0) {
134
135 /* force reset high (inactive) and unmask interrupts */
136 reset[1] = 0x7f;
137 ret = i2c_write_demod_bytes(state,
138 reset, sizeof(reset));
139 }
140 return ret;
141}
142
143static int lgdt3303_SwReset(struct lgdt330x_state* state)
144{
145 u8 ret;
146 u8 reset[] = {
147 0x02,
148 0x00 /* bit 0 is active low software reset */
149 };
150
151 ret = i2c_write_demod_bytes(state,
152 reset, sizeof(reset));
153 if (ret == 0) {
154
155 /* force reset high (inactive) */
156 reset[1] = 0x01;
157 ret = i2c_write_demod_bytes(state,
158 reset, sizeof(reset));
159 }
160 return ret;
161}
162
163static int lgdt330x_SwReset(struct lgdt330x_state* state)
164{
165 switch (state->config->demod_chip) {
166 case LGDT3302:
167 return lgdt3302_SwReset(state);
168 case LGDT3303:
169 return lgdt3303_SwReset(state);
170 default:
171 return -ENODEV;
172 }
173}
174
175#ifdef MUTE_TDA9887
176static int i2c_write_ntsc_demod (struct lgdt330x_state* state, u8 buf[2])
177{
178 struct i2c_msg msg =
179 { .addr = 0x43,
180 .flags = 0,
181 .buf = buf,
182 .len = 2 };
183 int err;
184
185 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
186 printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, msg.buf[0], msg.buf[1], err);
187 if (err < 0)
188 return err;
189 else
190 return -EREMOTEIO;
191 }
192 return 0;
193}
194
195static void fiddle_with_ntsc_if_demod(struct lgdt330x_state* state)
196{
197 // Experimental code
198 u8 buf0[] = {0x00, 0x20};
199 u8 buf1[] = {0x01, 0x00};
200 u8 buf2[] = {0x02, 0x00};
201
202 i2c_write_ntsc_demod(state, buf0);
203 i2c_write_ntsc_demod(state, buf1);
204 i2c_write_ntsc_demod(state, buf2);
205}
206#endif
207
208static int lgdt330x_init(struct dvb_frontend* fe)
209{
210 /* Hardware reset is done using gpio[0] of cx23880x chip.
211 * I'd like to do it here, but don't know how to find chip address.
212 * cx88-cards.c arranges for the reset bit to be inactive (high).
213 * Maybe there needs to be a callable function in cx88-core or
214 * the caller of this function needs to do it. */
215
216 /*
217 * Array of byte pairs <address, value>
218 * to initialize each different chip
219 */
220 static u8 lgdt3302_init_data[] = {
221 /* Use 50MHz parameter values from spec sheet since xtal is 50 */
222 /* Change the value of NCOCTFV[25:0] of carrier
223 recovery center frequency register */
224 VSB_CARRIER_FREQ0, 0x00,
225 VSB_CARRIER_FREQ1, 0x87,
226 VSB_CARRIER_FREQ2, 0x8e,
227 VSB_CARRIER_FREQ3, 0x01,
228 /* Change the TPCLK pin polarity
229 data is valid on falling clock */
230 DEMUX_CONTROL, 0xfb,
231 /* Change the value of IFBW[11:0] of
232 AGC IF/RF loop filter bandwidth register */
233 AGC_RF_BANDWIDTH0, 0x40,
234 AGC_RF_BANDWIDTH1, 0x93,
235 AGC_RF_BANDWIDTH2, 0x00,
236 /* Change the value of bit 6, 'nINAGCBY' and
237 'NSSEL[1:0] of ACG function control register 2 */
238 AGC_FUNC_CTRL2, 0xc6,
239 /* Change the value of bit 6 'RFFIX'
240 of AGC function control register 3 */
241 AGC_FUNC_CTRL3, 0x40,
242 /* Set the value of 'INLVTHD' register 0x2a/0x2c
243 to 0x7fe */
244 AGC_DELAY0, 0x07,
245 AGC_DELAY2, 0xfe,
246 /* Change the value of IAGCBW[15:8]
247 of inner AGC loop filter bandwith */
248 AGC_LOOP_BANDWIDTH0, 0x08,
249 AGC_LOOP_BANDWIDTH1, 0x9a
250 };
251
252 static u8 lgdt3303_init_data[] = {
253 0x4c, 0x14
254 };
255
256 struct lgdt330x_state* state = fe->demodulator_priv;
257 char *chip_name;
258 int err;
259
260 switch (state->config->demod_chip) {
261 case LGDT3302:
262 chip_name = "LGDT3302";
263 err = i2c_write_demod_bytes(state, lgdt3302_init_data,
264 sizeof(lgdt3302_init_data));
265 break;
266 case LGDT3303:
267 chip_name = "LGDT3303";
268 err = i2c_write_demod_bytes(state, lgdt3303_init_data,
269 sizeof(lgdt3303_init_data));
270#ifdef MUTE_TDA9887
271 fiddle_with_ntsc_if_demod(state);
272#endif
273 break;
274 default:
275 chip_name = "undefined";
276 printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n");
277 err = -ENODEV;
278 }
279 dprintk("%s entered as %s\n", __FUNCTION__, chip_name);
280 if (err < 0)
281 return err;
282 return lgdt330x_SwReset(state);
283}
284
285static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber)
286{
287 *ber = 0; /* Not supplied by the demod chips */
288 return 0;
289}
290
291static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
292{
293 struct lgdt330x_state* state = fe->demodulator_priv;
294 int err;
295 u8 buf[2];
296
297 switch (state->config->demod_chip) {
298 case LGDT3302:
299 err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
300 buf, sizeof(buf));
301 break;
302 case LGDT3303:
303 err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
304 buf, sizeof(buf));
305 break;
306 default:
307 printk(KERN_WARNING
308 "Only LGDT3302 and LGDT3303 are supported chips.\n");
309 err = -ENODEV;
310 }
311
312 *ucblocks = (buf[0] << 8) | buf[1];
313 return 0;
314}
315
316static int lgdt330x_set_parameters(struct dvb_frontend* fe,
317 struct dvb_frontend_parameters *param)
318{
319 /*
320 * Array of byte pairs <address, value>
321 * to initialize 8VSB for lgdt3303 chip 50 MHz IF
322 */
323 static u8 lgdt3303_8vsb_44_data[] = {
324 0x04, 0x00,
325 0x0d, 0x40,
326 0x0e, 0x87,
327 0x0f, 0x8e,
328 0x10, 0x01,
329 0x47, 0x8b };
330
331 /*
332 * Array of byte pairs <address, value>
333 * to initialize QAM for lgdt3303 chip
334 */
335 static u8 lgdt3303_qam_data[] = {
336 0x04, 0x00,
337 0x0d, 0x00,
338 0x0e, 0x00,
339 0x0f, 0x00,
340 0x10, 0x00,
341 0x51, 0x63,
342 0x47, 0x66,
343 0x48, 0x66,
344 0x4d, 0x1a,
345 0x49, 0x08,
346 0x4a, 0x9b };
347
348 struct lgdt330x_state* state = fe->demodulator_priv;
349
350 static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
351
352 int err;
353 /* Change only if we are actually changing the modulation */
354 if (state->current_modulation != param->u.vsb.modulation) {
355 switch(param->u.vsb.modulation) {
356 case VSB_8:
357 dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
358
359 /* Select VSB mode */
360 top_ctrl_cfg[1] = 0x03;
361
362 /* Select ANT connector if supported by card */
363 if (state->config->pll_rf_set)
364 state->config->pll_rf_set(fe, 1);
365
366 if (state->config->demod_chip == LGDT3303) {
367 err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data,
368 sizeof(lgdt3303_8vsb_44_data));
369 }
370 break;
371
372 case QAM_64:
373 dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
374
375 /* Select QAM_64 mode */
376 top_ctrl_cfg[1] = 0x00;
377
378 /* Select CABLE connector if supported by card */
379 if (state->config->pll_rf_set)
380 state->config->pll_rf_set(fe, 0);
381
382 if (state->config->demod_chip == LGDT3303) {
383 err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
384 sizeof(lgdt3303_qam_data));
385 }
386 break;
387
388 case QAM_256:
389 dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
390
391 /* Select QAM_256 mode */
392 top_ctrl_cfg[1] = 0x01;
393
394 /* Select CABLE connector if supported by card */
395 if (state->config->pll_rf_set)
396 state->config->pll_rf_set(fe, 0);
397
398 if (state->config->demod_chip == LGDT3303) {
399 err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
400 sizeof(lgdt3303_qam_data));
401 }
402 break;
403 default:
404 printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
405 return -1;
406 }
407 /*
408 * select serial or parallel MPEG harware interface
409 * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303
410 * Parallel: 0x00
411 */
412 top_ctrl_cfg[1] |= state->config->serial_mpeg;
413
414 /* Select the requested mode */
415 i2c_write_demod_bytes(state, top_ctrl_cfg,
416 sizeof(top_ctrl_cfg));
417 state->config->set_ts_params(fe, 0);
418 state->current_modulation = param->u.vsb.modulation;
419 }
420
421 /* Change only if we are actually changing the channel */
422 if (state->current_frequency != param->frequency) {
423 /* Tune to the new frequency */
424 state->config->pll_set(fe, param);
425 /* Keep track of the new frequency */
426 state->current_frequency = param->frequency;
427 }
428 lgdt330x_SwReset(state);
429 return 0;
430}
431
432static int lgdt330x_get_frontend(struct dvb_frontend* fe,
433 struct dvb_frontend_parameters* param)
434{
435 struct lgdt330x_state *state = fe->demodulator_priv;
436 param->frequency = state->current_frequency;
437 return 0;
438}
439
440static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
441{
442 struct lgdt330x_state* state = fe->demodulator_priv;
443 u8 buf[3];
444
445 *status = 0; /* Reset status result */
446
447 /* AGC status register */
448 i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
449 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
450 if ((buf[0] & 0x0c) == 0x8){
451 /* Test signal does not exist flag */
452 /* as well as the AGC lock flag. */
453 *status |= FE_HAS_SIGNAL;
454 } else {
455 /* Without a signal all other status bits are meaningless */
456 return 0;
457 }
458
459 /*
460 * You must set the Mask bits to 1 in the IRQ_MASK in order
461 * to see that status bit in the IRQ_STATUS register.
462 * This is done in SwReset();
463 */
464 /* signal status */
465 i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
466 dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
467
468
469 /* sync status */
470 if ((buf[2] & 0x03) == 0x01) {
471 *status |= FE_HAS_SYNC;
472 }
473
474 /* FEC error status */
475 if ((buf[2] & 0x0c) == 0x08) {
476 *status |= FE_HAS_LOCK;
477 *status |= FE_HAS_VITERBI;
478 }
479
480 /* Carrier Recovery Lock Status Register */
481 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
482 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
483 switch (state->current_modulation) {
484 case QAM_256:
485 case QAM_64:
486 /* Need to undestand why there are 3 lock levels here */
487 if ((buf[0] & 0x07) == 0x07)
488 *status |= FE_HAS_CARRIER;
489 break;
490 case VSB_8:
491 if ((buf[0] & 0x80) == 0x80)
492 *status |= FE_HAS_CARRIER;
493 break;
494 default:
495 printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
496 }
497
498 return 0;
499}
500
501static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
502{
503 struct lgdt330x_state* state = fe->demodulator_priv;
504 int err;
505 u8 buf[3];
506
507 *status = 0; /* Reset status result */
508
509 /* lgdt3303 AGC status register */
510 err = i2c_read_demod_bytes(state, 0x58, buf, 1);
511 if (err < 0)
512 return err;
513
514 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
515 if ((buf[0] & 0x21) == 0x01){
516 /* Test input signal does not exist flag */
517 /* as well as the AGC lock flag. */
518 *status |= FE_HAS_SIGNAL;
519 } else {
520 /* Without a signal all other status bits are meaningless */
521 return 0;
522 }
523
524 /* Carrier Recovery Lock Status Register */
525 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
526 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
527 switch (state->current_modulation) {
528 case QAM_256:
529 case QAM_64:
530 /* Need to undestand why there are 3 lock levels here */
531 if ((buf[0] & 0x07) == 0x07)
532 *status |= FE_HAS_CARRIER;
533 else
534 break;
535 i2c_read_demod_bytes(state, 0x8a, buf, 1);
536 if ((buf[0] & 0x04) == 0x04)
537 *status |= FE_HAS_SYNC;
538 if ((buf[0] & 0x01) == 0x01)
539 *status |= FE_HAS_LOCK;
540 if ((buf[0] & 0x08) == 0x08)
541 *status |= FE_HAS_VITERBI;
542 break;
543 case VSB_8:
544 if ((buf[0] & 0x80) == 0x80)
545 *status |= FE_HAS_CARRIER;
546 else
547 break;
548 i2c_read_demod_bytes(state, 0x38, buf, 1);
549 if ((buf[0] & 0x02) == 0x00)
550 *status |= FE_HAS_SYNC;
551 if ((buf[0] & 0x01) == 0x01) {
552 *status |= FE_HAS_LOCK;
553 *status |= FE_HAS_VITERBI;
554 }
555 break;
556 default:
557 printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
558 }
559 return 0;
560}
561
562static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
563{
564 /* not directly available. */
565 *strength = 0;
566 return 0;
567}
568
569static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
570{
571#ifdef SNR_IN_DB
572 /*
573 * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
574 * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
575 * respectively. The following tables are built on these formulas.
576 * The usual definition is SNR = 20 log10(signal/noise)
577 * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
578 *
579 * This table is a an ordered list of noise values computed by the
580 * formula from the spec sheet such that the index into the table
581 * starting at 43 or 45 is the SNR value in db. There are duplicate noise
582 * value entries at the beginning because the SNR varies more than
583 * 1 db for a change of 1 digit in noise at very small values of noise.
584 *
585 * Examples from SNR_EQ table:
586 * noise SNR
587 * 0 43
588 * 1 42
589 * 2 39
590 * 3 37
591 * 4 36
592 * 5 35
593 * 6 34
594 * 7 33
595 * 8 33
596 * 9 32
597 * 10 32
598 * 11 31
599 * 12 31
600 * 13 30
601 */
602
603 static const u32 SNR_EQ[] =
604 { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7,
605 9, 11, 13, 17, 21, 26, 33, 41, 52, 65,
606 81, 102, 129, 162, 204, 257, 323, 406, 511, 644,
607 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433,
608 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323,
609 80978, 101945, 128341, 161571, 203406, 256073, 0x40000
610 };
611
612 static const u32 SNR_PH[] =
613 { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8,
614 10, 12, 15, 19, 23, 29, 37, 46, 58, 73,
615 91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
616 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
617 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
618 90833, 114351, 143960, 181235, 228161, 0x080000
619 };
620
621 static u8 buf[5];/* read data buffer */
622 static u32 noise; /* noise value */
623 static u32 snr_db; /* index into SNR_EQ[] */
624 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
625
626 /* read both equalizer and phase tracker noise data */
627 i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
628
629 if (state->current_modulation == VSB_8) {
630 /* Equalizer Mean-Square Error Register for VSB */
631 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
632
633 /*
634 * Look up noise value in table.
635 * A better search algorithm could be used...
636 * watch out there are duplicate entries.
637 */
638 for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
639 if (noise < SNR_EQ[snr_db]) {
640 *snr = 43 - snr_db;
641 break;
642 }
643 }
644 } else {
645 /* Phase Tracker Mean-Square Error Register for QAM */
646 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
647
648 /* Look up noise value in table. */
649 for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
650 if (noise < SNR_PH[snr_db]) {
651 *snr = 45 - snr_db;
652 break;
653 }
654 }
655 }
656#else
657 /* Return the raw noise value */
658 static u8 buf[5];/* read data buffer */
659 static u32 noise; /* noise value */
660 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
661
662 /* read both equalizer and pase tracker noise data */
663 i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
664
665 if (state->current_modulation == VSB_8) {
666 /* Phase Tracker Mean-Square Error Register for VSB */
667 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
668 } else {
669
670 /* Carrier Recovery Mean-Square Error for QAM */
671 i2c_read_demod_bytes(state, 0x1a, buf, 2);
672 noise = ((buf[0] & 3) << 8) | buf[1];
673 }
674
675 /* Small values for noise mean signal is better so invert noise */
676 *snr = ~noise;
677#endif
678
679 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
680
681 return 0;
682}
683
684static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
685{
686 /* Return the raw noise value */
687 static u8 buf[5];/* read data buffer */
688 static u32 noise; /* noise value */
689 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
690
691 if (state->current_modulation == VSB_8) {
692
693 /* Phase Tracker Mean-Square Error Register for VSB */
694 noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
695 } else {
696
697 /* Carrier Recovery Mean-Square Error for QAM */
698 i2c_read_demod_bytes(state, 0x1a, buf, 2);
699 noise = (buf[0] << 8) | buf[1];
700 }
701
702 /* Small values for noise mean signal is better so invert noise */
703 *snr = ~noise;
704
705 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
706
707 return 0;
708}
709
710static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
711{
712 /* I have no idea about this - it may not be needed */
713 fe_tune_settings->min_delay_ms = 500;
714 fe_tune_settings->step_size = 0;
715 fe_tune_settings->max_drift = 0;
716 return 0;
717}
718
719static void lgdt330x_release(struct dvb_frontend* fe)
720{
721 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
722 kfree(state);
723}
724
725static struct dvb_frontend_ops lgdt3302_ops;
726static struct dvb_frontend_ops lgdt3303_ops;
727
728struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
729 struct i2c_adapter* i2c)
730{
731 struct lgdt330x_state* state = NULL;
732 u8 buf[1];
733
734 /* Allocate memory for the internal state */
735 state = (struct lgdt330x_state*) kmalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
736 if (state == NULL)
737 goto error;
738 memset(state,0,sizeof(*state));
739
740 /* Setup the state */
741 state->config = config;
742 state->i2c = i2c;
743 switch (config->demod_chip) {
744 case LGDT3302:
745 memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
746 break;
747 case LGDT3303:
748 memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
749 break;
750 default:
751 goto error;
752 }
753
754 /* Verify communication with demod chip */
755 if (i2c_read_demod_bytes(state, 2, buf, 1))
756 goto error;
757
758 state->current_frequency = -1;
759 state->current_modulation = -1;
760
761 /* Create dvb_frontend */
762 state->frontend.ops = &state->ops;
763 state->frontend.demodulator_priv = state;
764 return &state->frontend;
765
766error:
767 if (state)
768 kfree(state);
769 dprintk("%s: ERROR\n",__FUNCTION__);
770 return NULL;
771}
772
773static struct dvb_frontend_ops lgdt3302_ops = {
774 .info = {
775 .name= "LG Electronics LGDT3302/LGDT3303 VSB/QAM Frontend",
776 .type = FE_ATSC,
777 .frequency_min= 54000000,
778 .frequency_max= 858000000,
779 .frequency_stepsize= 62500,
780 /* Symbol rate is for all VSB modes need to check QAM */
781 .symbol_rate_min = 10762000,
782 .symbol_rate_max = 10762000,
783 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
784 },
785 .init = lgdt330x_init,
786 .set_frontend = lgdt330x_set_parameters,
787 .get_frontend = lgdt330x_get_frontend,
788 .get_tune_settings = lgdt330x_get_tune_settings,
789 .read_status = lgdt3302_read_status,
790 .read_ber = lgdt330x_read_ber,
791 .read_signal_strength = lgdt330x_read_signal_strength,
792 .read_snr = lgdt3302_read_snr,
793 .read_ucblocks = lgdt330x_read_ucblocks,
794 .release = lgdt330x_release,
795};
796
797static struct dvb_frontend_ops lgdt3303_ops = {
798 .info = {
799 .name= "LG Electronics LGDT3303 VSB/QAM Frontend",
800 .type = FE_ATSC,
801 .frequency_min= 54000000,
802 .frequency_max= 858000000,
803 .frequency_stepsize= 62500,
804 /* Symbol rate is for all VSB modes need to check QAM */
805 .symbol_rate_min = 10762000,
806 .symbol_rate_max = 10762000,
807 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
808 },
809 .init = lgdt330x_init,
810 .set_frontend = lgdt330x_set_parameters,
811 .get_frontend = lgdt330x_get_frontend,
812 .get_tune_settings = lgdt330x_get_tune_settings,
813 .read_status = lgdt3303_read_status,
814 .read_ber = lgdt330x_read_ber,
815 .read_signal_strength = lgdt330x_read_signal_strength,
816 .read_snr = lgdt3303_read_snr,
817 .read_ucblocks = lgdt330x_read_ucblocks,
818 .release = lgdt330x_release,
819};
820
821MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
822MODULE_AUTHOR("Wilson Michaels");
823MODULE_LICENSE("GPL");
824
825EXPORT_SYMBOL(lgdt330x_attach);
826
827/*
828 * Local variables:
829 * c-basic-offset: 8
830 * End:
831 */
diff --git a/drivers/media/dvb/frontends/lgdt3302.h b/drivers/media/dvb/frontends/lgdt330x.h
index 81587a40032b..e209ba1e47c5 100644
--- a/drivers/media/dvb/frontends/lgdt3302.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -1,7 +1,5 @@
1/* 1/*
2 * $Id: lgdt3302.h,v 1.2 2005/06/28 23:50:48 mkrufky Exp $ 2 * Support for LGDT3302 and LGDT3303 - VSB/QAM
3 *
4 * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
5 * 3 *
6 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> 4 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
7 * 5 *
@@ -21,26 +19,40 @@
21 * 19 *
22 */ 20 */
23 21
24#ifndef LGDT3302_H 22#ifndef LGDT330X_H
25#define LGDT3302_H 23#define LGDT330X_H
26 24
27#include <linux/dvb/frontend.h> 25#include <linux/dvb/frontend.h>
28 26
29struct lgdt3302_config 27typedef enum lg_chip_t {
28 UNDEFINED,
29 LGDT3302,
30 LGDT3303
31}lg_chip_type;
32
33struct lgdt330x_config
30{ 34{
31 /* The demodulator's i2c address */ 35 /* The demodulator's i2c address */
32 u8 demod_address; 36 u8 demod_address;
33 u8 pll_address; 37
34 struct dvb_pll_desc *pll_desc; 38 /* LG demodulator chip LGDT3302 or LGDT3303 */
39 lg_chip_type demod_chip;
40
41 /* MPEG hardware interface - 0:parallel 1:serial */
42 int serial_mpeg;
43
44 /* PLL interface */
45 int (*pll_rf_set) (struct dvb_frontend* fe, int index);
46 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
35 47
36 /* Need to set device param for start_dma */ 48 /* Need to set device param for start_dma */
37 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
38}; 50};
39 51
40extern struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config, 52extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
41 struct i2c_adapter* i2c); 53 struct i2c_adapter* i2c);
42 54
43#endif /* LGDT3302_H */ 55#endif /* LGDT330X_H */
44 56
45/* 57/*
46 * Local variables: 58 * Local variables:
diff --git a/drivers/media/dvb/frontends/lgdt3302_priv.h b/drivers/media/dvb/frontends/lgdt330x_priv.h
index 6193fa7a569d..59b7c5b9012d 100644
--- a/drivers/media/dvb/frontends/lgdt3302_priv.h
+++ b/drivers/media/dvb/frontends/lgdt330x_priv.h
@@ -1,7 +1,5 @@
1/* 1/*
2 * $Id: lgdt3302_priv.h,v 1.2 2005/06/28 23:50:48 mkrufky Exp $ 2 * Support for LGDT3302 and LGDT3303 - VSB/QAM
3 *
4 * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
5 * 3 *
6 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> 4 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
7 * 5 *
@@ -21,8 +19,8 @@
21 * 19 *
22 */ 20 */
23 21
24#ifndef _LGDT3302_PRIV_ 22#ifndef _LGDT330X_PRIV_
25#define _LGDT3302_PRIV_ 23#define _LGDT330X_PRIV_
26 24
27/* i2c control register addresses */ 25/* i2c control register addresses */
28enum I2C_REG { 26enum I2C_REG {
@@ -59,11 +57,13 @@ enum I2C_REG {
59 PH_ERR1= 0x4a, 57 PH_ERR1= 0x4a,
60 PH_ERR2= 0x4b, 58 PH_ERR2= 0x4b,
61 DEMUX_CONTROL= 0x66, 59 DEMUX_CONTROL= 0x66,
62 PACKET_ERR_COUNTER1= 0x6a, 60 LGDT3302_PACKET_ERR_COUNTER1= 0x6a,
63 PACKET_ERR_COUNTER2= 0x6b, 61 LGDT3302_PACKET_ERR_COUNTER2= 0x6b,
62 LGDT3303_PACKET_ERR_COUNTER1= 0x8b,
63 LGDT3303_PACKET_ERR_COUNTER2= 0x8c,
64}; 64};
65 65
66#endif /* _LGDT3302_PRIV_ */ 66#endif /* _LGDT330X_PRIV_ */
67 67
68/* 68/*
69 * Local variables: 69 * Local variables: