blob: c3b8d4e080bbf1977ad2e25cab960ddfeaf5c2d0 [file] [log] [blame]
Mac Michaelsd8667cb2005-07-07 17:58:29 -07001/*
Mac Michaelsd8667cb2005-07-07 17:58:29 -07002 * 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
Mac Michaelsd8667cb2005-07-07 17:58:29 -070035#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{
Michael Krufkyb6aef072005-07-27 11:45:54 -070077 u8 tmp[] = { buf[0], buf[1] };
78 struct i2c_msg msg =
79 { .addr = addr, .flags = 0, .buf = tmp, .len = 2 };
80 int err;
81 int i;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070082
Michael Krufkyb6aef072005-07-27 11:45:54 -070083 for (i=1; i<len; i++) {
84 tmp[1] = buf[i];
Mac Michaelsd8667cb2005-07-07 17:58:29 -070085 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
86 printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
Michael Krufky58ba0062005-07-12 13:58:37 -070087 if (err < 0)
88 return err;
89 else
90 return -EREMOTEIO;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070091 }
Michael Krufkyb6aef072005-07-27 11:45:54 -070092 tmp[0]++;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070093 }
94 return 0;
95}
Michael Krufkyb6aef072005-07-27 11:45:54 -070096
Michael Krufky723d52e2005-07-27 11:45:56 -070097#if 0
Mac Michaelsd8667cb2005-07-07 17:58:29 -070098static int i2c_readbytes (struct lgdt3302_state* state,
99 u8 addr, /* demod_address or pll_address */
100 u8 *buf, /* holds data bytes read */
101 int len /* number of bytes to read */ )
102{
103 struct i2c_msg msg =
104 { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
105 int err;
106
107 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
108 printk(KERN_WARNING "lgdt3302: %s error (addr %02x, err == %i)\n", __FUNCTION__, addr, err);
109 return -EREMOTEIO;
110 }
111 return 0;
112}
Michael Krufky723d52e2005-07-27 11:45:56 -0700113#endif
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700114
115/*
116 * This routine writes the register (reg) to the demod bus
117 * then reads the data returned for (len) bytes.
118 */
119
120static u8 i2c_selectreadbytes (struct lgdt3302_state* state,
121 enum I2C_REG reg, u8* buf, int len)
122{
123 u8 wr [] = { reg };
124 struct i2c_msg msg [] = {
125 { .addr = state->config->demod_address,
126 .flags = 0, .buf = wr, .len = 1 },
127 { .addr = state->config->demod_address,
128 .flags = I2C_M_RD, .buf = buf, .len = len },
129 };
130 int ret;
131 ret = i2c_transfer(state->i2c, msg, 2);
132 if (ret != 2) {
133 printk(KERN_WARNING "lgdt3302: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
134 } else {
135 ret = 0;
136 }
137 return ret;
138}
139
140/* Software reset */
141int lgdt3302_SwReset(struct lgdt3302_state* state)
142{
143 u8 ret;
144 u8 reset[] = {
145 IRQ_MASK,
146 0x00 /* bit 6 is active low software reset
147 * bits 5-0 are 1 to mask interrupts */
148 };
149
150 ret = i2c_writebytes(state,
151 state->config->demod_address,
152 reset, sizeof(reset));
153 if (ret == 0) {
154 /* spec says reset takes 100 ns why wait */
155 /* mdelay(100); */ /* keep low for 100mS */
156 reset[1] = 0x7f; /* force reset high (inactive)
157 * and unmask interrupts */
158 ret = i2c_writebytes(state,
159 state->config->demod_address,
160 reset, sizeof(reset));
161 }
162 /* Spec does not indicate a need for this either */
163 /*mdelay(5); */ /* wait 5 msec before doing more */
164 return ret;
165}
166
167static int lgdt3302_init(struct dvb_frontend* fe)
168{
169 /* Hardware reset is done using gpio[0] of cx23880x chip.
170 * I'd like to do it here, but don't know how to find chip address.
171 * cx88-cards.c arranges for the reset bit to be inactive (high).
172 * Maybe there needs to be a callable function in cx88-core or
173 * the caller of this function needs to do it. */
174
175 dprintk("%s entered\n", __FUNCTION__);
176 return lgdt3302_SwReset((struct lgdt3302_state*) fe->demodulator_priv);
177}
178
179static int lgdt3302_read_ber(struct dvb_frontend* fe, u32* ber)
180{
181 *ber = 0; /* Dummy out for now */
182 return 0;
183}
184
185static int lgdt3302_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
186{
187 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
188 u8 buf[2];
189
190 i2c_selectreadbytes(state, PACKET_ERR_COUNTER1, buf, sizeof(buf));
191
192 *ucblocks = (buf[0] << 8) | buf[1];
193 return 0;
194}
195
196static int lgdt3302_set_parameters(struct dvb_frontend* fe,
197 struct dvb_frontend_parameters *param)
198{
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700199 struct lgdt3302_state* state =
200 (struct lgdt3302_state*) fe->demodulator_priv;
201
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700202 /* Use 50MHz parameter values from spec sheet since xtal is 50 */
203 static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
204 static u8 vsb_freq_cfg[] = { VSB_CARRIER_FREQ0, 0x00, 0x87, 0x8e, 0x01 };
205 static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };
206 static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
207 static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 };
Michael Krufky3952db62005-07-14 00:33:33 -0700208 static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x07, 0x00, 0xfe };
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700209 static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };
210
211 /* Change only if we are actually changing the modulation */
212 if (state->current_modulation != param->u.vsb.modulation) {
213 switch(param->u.vsb.modulation) {
214 case VSB_8:
215 dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
216
217 /* Select VSB mode and serial MPEG interface */
218 top_ctrl_cfg[1] = 0x07;
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700219
220 /* Select ANT connector if supported by card */
221 if (state->config->pll_rf_set)
222 state->config->pll_rf_set(fe, 1);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700223 break;
224
225 case QAM_64:
226 dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
227
228 /* Select QAM_64 mode and serial MPEG interface */
229 top_ctrl_cfg[1] = 0x04;
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700230
231 /* Select CABLE connector if supported by card */
232 if (state->config->pll_rf_set)
233 state->config->pll_rf_set(fe, 0);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700234 break;
235
236 case QAM_256:
237 dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
238
239 /* Select QAM_256 mode and serial MPEG interface */
240 top_ctrl_cfg[1] = 0x05;
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700241
242 /* Select CABLE connector if supported by card */
243 if (state->config->pll_rf_set)
244 state->config->pll_rf_set(fe, 0);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700245 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
Michael Krufky58ba0062005-07-12 13:58:37 -0700273 /* Change the value of NCOCTFV[25:0] of carrier
274 recovery center frequency register */
275 i2c_writebytes(state, state->config->demod_address,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700276 vsb_freq_cfg, sizeof(vsb_freq_cfg));
Michael Krufky3952db62005-07-14 00:33:33 -0700277
278 /* Set the value of 'INLVTHD' register 0x2a/0x2c to 0x7fe */
Michael Krufky58ba0062005-07-12 13:58:37 -0700279 i2c_writebytes(state, state->config->demod_address,
280 agc_delay_cfg, sizeof(agc_delay_cfg));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700281
Michael Krufky58ba0062005-07-12 13:58:37 -0700282 /* 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));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700286
287 state->config->set_ts_params(fe, 0);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700288 state->current_modulation = param->u.vsb.modulation;
289 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700290
291 /* Change only if we are actually changing the channel */
292 if (state->current_frequency != param->frequency) {
Michael Krufkyb6aef072005-07-27 11:45:54 -0700293 u8 buf[5];
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700294
Michael Krufkyb6aef072005-07-27 11:45:54 -0700295 /* This must be done before the initialized msg is declared */
296 state->config->pll_set(fe, param, buf);
297
298 struct i2c_msg msg =
299 { .addr = buf[0], .flags = 0, .buf = &buf[1], .len = 4 };
300 int err;
301
302 dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x "
303 "0x%02x 0x%02x\n", __FUNCTION__,
304 buf[0],buf[1],buf[2],buf[3],buf[4]);
305 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
306 printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, buf[0], buf[1], err);
307 if (err < 0)
308 return err;
309 else
310 return -EREMOTEIO;
311 }
312#if 0
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700313 /* Check the status of the tuner pll */
Michael Krufkyb6aef072005-07-27 11:45:54 -0700314 i2c_readbytes(state, buf[0], &buf[1], 1);
315 dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[1]);
316#endif
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700317 /* Update current frequency */
318 state->current_frequency = param->frequency;
319 }
Michael Krufky58ba0062005-07-12 13:58:37 -0700320 lgdt3302_SwReset(state);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700321 return 0;
322}
323
324static int lgdt3302_get_frontend(struct dvb_frontend* fe,
325 struct dvb_frontend_parameters* param)
326{
327 struct lgdt3302_state *state = fe->demodulator_priv;
328 param->frequency = state->current_frequency;
329 return 0;
330}
331
332static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
333{
334 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
335 u8 buf[3];
336
337 *status = 0; /* Reset status result */
338
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700339 /*
340 * You must set the Mask bits to 1 in the IRQ_MASK in order
341 * to see that status bit in the IRQ_STATUS register.
342 * This is done in SwReset();
343 */
344
Michael Krufky08d80522005-07-07 17:58:43 -0700345 /* AGC status register */
346 i2c_selectreadbytes(state, AGC_STATUS, buf, 1);
347 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
348 if ((buf[0] & 0x0c) == 0x8){
349 /* Test signal does not exist flag */
350 /* as well as the AGC lock flag. */
351 *status |= FE_HAS_SIGNAL;
352 } else {
353 /* Without a signal all other status bits are meaningless */
354 return 0;
355 }
356
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700357 /* signal status */
358 i2c_selectreadbytes(state, TOP_CONTROL, buf, sizeof(buf));
359 dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
Michael Krufky08d80522005-07-07 17:58:43 -0700360
361#if 0
362 /* Alternative method to check for a signal */
363 /* using the SNR good/bad interrupts. */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700364 if ((buf[2] & 0x30) == 0x10)
365 *status |= FE_HAS_SIGNAL;
Michael Krufky08d80522005-07-07 17:58:43 -0700366#endif
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700367
368 /* sync status */
369 if ((buf[2] & 0x03) == 0x01) {
370 *status |= FE_HAS_SYNC;
371 }
372
373 /* FEC error status */
374 if ((buf[2] & 0x0c) == 0x08) {
375 *status |= FE_HAS_LOCK;
376 *status |= FE_HAS_VITERBI;
377 }
378
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700379 /* Carrier Recovery Lock Status Register */
380 i2c_selectreadbytes(state, CARRIER_LOCK, buf, 1);
381 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
382 switch (state->current_modulation) {
383 case QAM_256:
384 case QAM_64:
385 /* Need to undestand why there are 3 lock levels here */
386 if ((buf[0] & 0x07) == 0x07)
387 *status |= FE_HAS_CARRIER;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700388 break;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700389 case VSB_8:
390 if ((buf[0] & 0x80) == 0x80)
391 *status |= FE_HAS_CARRIER;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700392 break;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700393 default:
394 printk("KERN_WARNING lgdt3302: %s: Modulation set to unsupported value\n", __FUNCTION__);
395 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700396
397 return 0;
398}
399
400static int lgdt3302_read_signal_strength(struct dvb_frontend* fe, u16* strength)
401{
402 /* not directly available. */
403 return 0;
404}
405
406static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
407{
408#ifdef SNR_IN_DB
409 /*
410 * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
411 * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
412 * respectively. The following tables are built on these formulas.
413 * The usual definition is SNR = 20 log10(signal/noise)
414 * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
415 *
416 * This table is a an ordered list of noise values computed by the
417 * formula from the spec sheet such that the index into the table
418 * starting at 43 or 45 is the SNR value in db. There are duplicate noise
419 * value entries at the beginning because the SNR varies more than
420 * 1 db for a change of 1 digit in noise at very small values of noise.
421 *
422 * Examples from SNR_EQ table:
423 * noise SNR
424 * 0 43
425 * 1 42
426 * 2 39
427 * 3 37
428 * 4 36
429 * 5 35
430 * 6 34
431 * 7 33
432 * 8 33
433 * 9 32
434 * 10 32
435 * 11 31
436 * 12 31
437 * 13 30
438 */
439
440 static const u32 SNR_EQ[] =
441 { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7,
442 9, 11, 13, 17, 21, 26, 33, 41, 52, 65,
443 81, 102, 129, 162, 204, 257, 323, 406, 511, 644,
444 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433,
445 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323,
446 80978, 101945, 128341, 161571, 203406, 256073, 0x40000
447 };
448
449 static const u32 SNR_PH[] =
450 { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8,
451 10, 12, 15, 19, 23, 29, 37, 46, 58, 73,
452 91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
453 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
454 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
455 90833, 114351, 143960, 181235, 228161, 0x040000
456 };
457
458 static u8 buf[5];/* read data buffer */
459 static u32 noise; /* noise value */
460 static u32 snr_db; /* index into SNR_EQ[] */
461 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
462
463 /* read both equalizer and pase tracker noise data */
464 i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
465
466 if (state->current_modulation == VSB_8) {
467 /* Equalizer Mean-Square Error Register for VSB */
468 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
469
470 /*
471 * Look up noise value in table.
472 * A better search algorithm could be used...
473 * watch out there are duplicate entries.
474 */
475 for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
476 if (noise < SNR_EQ[snr_db]) {
477 *snr = 43 - snr_db;
478 break;
479 }
480 }
481 } else {
482 /* Phase Tracker Mean-Square Error Register for QAM */
483 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
484
485 /* Look up noise value in table. */
486 for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
487 if (noise < SNR_PH[snr_db]) {
488 *snr = 45 - snr_db;
489 break;
490 }
491 }
492 }
493#else
494 /* Return the raw noise value */
495 static u8 buf[5];/* read data buffer */
496 static u32 noise; /* noise value */
497 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
498
499 /* read both equalizer and pase tracker noise data */
500 i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
501
502 if (state->current_modulation == VSB_8) {
503 /* Equalizer Mean-Square Error Register for VSB */
504 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
505 } else {
506 /* Phase Tracker Mean-Square Error Register for QAM */
507 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
508 }
509
510 /* Small values for noise mean signal is better so invert noise */
511 /* Noise is 19 bit value so discard 3 LSB*/
512 *snr = ~noise>>3;
513#endif
514
515 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
516
517 return 0;
518}
519
520static int lgdt3302_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
521{
522 /* I have no idea about this - it may not be needed */
523 fe_tune_settings->min_delay_ms = 500;
524 fe_tune_settings->step_size = 0;
525 fe_tune_settings->max_drift = 0;
526 return 0;
527}
528
529static void lgdt3302_release(struct dvb_frontend* fe)
530{
531 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
532 kfree(state);
533}
534
535static struct dvb_frontend_ops lgdt3302_ops;
536
537struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config,
538 struct i2c_adapter* i2c)
539{
540 struct lgdt3302_state* state = NULL;
541 u8 buf[1];
542
543 /* Allocate memory for the internal state */
544 state = (struct lgdt3302_state*) kmalloc(sizeof(struct lgdt3302_state), GFP_KERNEL);
545 if (state == NULL)
546 goto error;
547 memset(state,0,sizeof(*state));
548
549 /* Setup the state */
550 state->config = config;
551 state->i2c = i2c;
552 memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
553 /* Verify communication with demod chip */
554 if (i2c_selectreadbytes(state, 2, buf, 1))
555 goto error;
556
557 state->current_frequency = -1;
558 state->current_modulation = -1;
559
560 /* Create dvb_frontend */
561 state->frontend.ops = &state->ops;
562 state->frontend.demodulator_priv = state;
563 return &state->frontend;
564
565error:
566 if (state)
567 kfree(state);
568 dprintk("%s: ERROR\n",__FUNCTION__);
569 return NULL;
570}
571
572static struct dvb_frontend_ops lgdt3302_ops = {
573 .info = {
574 .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
575 .type = FE_ATSC,
576 .frequency_min= 54000000,
577 .frequency_max= 858000000,
578 .frequency_stepsize= 62500,
579 /* Symbol rate is for all VSB modes need to check QAM */
580 .symbol_rate_min = 10762000,
581 .symbol_rate_max = 10762000,
582 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
583 },
584 .init = lgdt3302_init,
585 .set_frontend = lgdt3302_set_parameters,
586 .get_frontend = lgdt3302_get_frontend,
587 .get_tune_settings = lgdt3302_get_tune_settings,
588 .read_status = lgdt3302_read_status,
589 .read_ber = lgdt3302_read_ber,
590 .read_signal_strength = lgdt3302_read_signal_strength,
591 .read_snr = lgdt3302_read_snr,
592 .read_ucblocks = lgdt3302_read_ucblocks,
593 .release = lgdt3302_release,
594};
595
596MODULE_DESCRIPTION("LGDT3302 [DViCO FusionHDTV 3 Gold] (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
597MODULE_AUTHOR("Wilson Michaels");
598MODULE_LICENSE("GPL");
599
600EXPORT_SYMBOL(lgdt3302_attach);
601
602/*
603 * Local variables:
604 * c-basic-offset: 8
605 * compile-command: "make DVB=1"
606 * End:
607 */