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