[PATCH] dvb: LGDT3302 QAM256 initialization fix
[safe/jmp/linux-2.6] / drivers / media / dvb / frontends / lgdt3302.c
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
47 static int debug = 0;
48 module_param(debug, int, 0644);
49 MODULE_PARM_DESC(debug,"Turn on/off lgdt3302 frontend debugging (default:off).");
50 #define dprintk(args...) \
51 do { \
52 if (debug) printk(KERN_DEBUG "lgdt3302: " args); \
53 } while (0)
54
55 struct 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
72 static 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 }
110 static 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
131 static 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 */
152 int 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
178 static 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
190 static int lgdt3302_read_ber(struct dvb_frontend* fe, u32* ber)
191 {
192         *ber = 0; /* Dummy out for now */
193         return 0;
194 }
195
196 static 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
207 static 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, 0x00, 0x00, 0x00 };
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                 int value;
226
227                 switch(param->u.vsb.modulation) {
228                 case VSB_8:
229                         dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
230
231                         /* Select VSB mode and serial MPEG interface */
232                         top_ctrl_cfg[1] = 0x07;
233                         break;
234
235                 case QAM_64:
236                         dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
237
238                         /* Select QAM_64 mode and serial MPEG interface */
239                         top_ctrl_cfg[1] = 0x04;
240                         break;
241
242                 case QAM_256:
243                         dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
244
245                         /* Select QAM_256 mode and serial MPEG interface */
246                         top_ctrl_cfg[1] = 0x05;
247                         break;
248                 default:
249                         printk(KERN_WARNING "lgdt3302: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
250                         return -1;
251                 }
252                 /* Initializations common to all modes */
253
254                 /* Select the requested mode */
255                 i2c_writebytes(state, state->config->demod_address,
256                                top_ctrl_cfg, sizeof(top_ctrl_cfg));
257
258                 /* Change the value of IFBW[11:0]
259                    of AGC IF/RF loop filter bandwidth register */
260                 i2c_writebytes(state, state->config->demod_address,
261                                agc_rf_cfg, sizeof(agc_rf_cfg));
262
263                 /* Change the value of bit 6, 'nINAGCBY' and
264                    'NSSEL[1:0] of ACG function control register 2 */
265                 /* Change the value of bit 6 'RFFIX'
266                    of AGC function control register 3 */
267                 i2c_writebytes(state, state->config->demod_address,
268                                agc_ctrl_cfg, sizeof(agc_ctrl_cfg));
269
270                 /* Change the TPCLK pin polarity
271                    data is valid on falling clock */
272                 i2c_writebytes(state, state->config->demod_address,
273                                demux_ctrl_cfg, sizeof(demux_ctrl_cfg));
274
275                 /* Change the value of NCOCTFV[25:0] of carrier
276                    recovery center frequency register */
277                 i2c_writebytes(state, state->config->demod_address,
278                                        vsb_freq_cfg, sizeof(vsb_freq_cfg));
279                 /* Set the value of 'INLVTHD' register 0x2a/0x2c
280                    to value from 'IFACC' register 0x39/0x3b -1 */
281                 i2c_selectreadbytes(state, AGC_RFIF_ACC0,
282                                     &agc_delay_cfg[1], 3);
283                 value = ((agc_delay_cfg[1] & 0x0f) << 8) | agc_delay_cfg[3];
284                 value = value -1;
285                 dprintk("%s IFACC -1 = 0x%03x\n", __FUNCTION__, value);
286                 agc_delay_cfg[1] = (value >> 8) & 0x0f;
287                 agc_delay_cfg[2] = 0x00;
288                 agc_delay_cfg[3] = value & 0xff;
289                 i2c_writebytes(state, state->config->demod_address,
290                                agc_delay_cfg, sizeof(agc_delay_cfg));
291
292                 /* Change the value of IAGCBW[15:8]
293                    of inner AGC loop filter bandwith */
294                 i2c_writebytes(state, state->config->demod_address,
295                                agc_loop_cfg, sizeof(agc_loop_cfg));
296
297                 state->config->set_ts_params(fe, 0);
298                 state->current_modulation = param->u.vsb.modulation;
299         }
300
301         /* Change only if we are actually changing the channel */
302         if (state->current_frequency != param->frequency) {
303                 dvb_pll_configure(state->config->pll_desc, buf,
304                                   param->frequency, 0);
305                 dprintk("%s: tuner bytes: 0x%02x 0x%02x "
306                         "0x%02x 0x%02x\n", __FUNCTION__, buf[0],buf[1],buf[2],buf[3]);
307                 i2c_writebytes(state, state->config->pll_address ,buf, 4);
308
309                 /* Check the status of the tuner pll */
310                 i2c_readbytes(state, state->config->pll_address, buf, 1);
311                 dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
312
313                 /* Update current frequency */
314                 state->current_frequency = param->frequency;
315         }
316         lgdt3302_SwReset(state);
317         return 0;
318 }
319
320 static int lgdt3302_get_frontend(struct dvb_frontend* fe,
321                                  struct dvb_frontend_parameters* param)
322 {
323         struct lgdt3302_state *state = fe->demodulator_priv;
324         param->frequency = state->current_frequency;
325         return 0;
326 }
327
328 static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
329 {
330         struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
331         u8 buf[3];
332
333         *status = 0; /* Reset status result */
334
335         /* Check the status of the tuner pll */
336         i2c_readbytes(state, state->config->pll_address, buf, 1);
337         dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
338         if ((buf[0] & 0xc0) != 0x40)
339                 return 0; /* Tuner PLL not locked or not powered on */
340
341         /*
342          * You must set the Mask bits to 1 in the IRQ_MASK in order
343          * to see that status bit in the IRQ_STATUS register.
344          * This is done in SwReset();
345          */
346
347         /* AGC status register */
348         i2c_selectreadbytes(state, AGC_STATUS, buf, 1);
349         dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
350         if ((buf[0] & 0x0c) == 0x8){
351                 /* Test signal does not exist flag */
352                 /* as well as the AGC lock flag.   */
353                 *status |= FE_HAS_SIGNAL;
354         } else {
355                 /* Without a signal all other status bits are meaningless */
356                 return 0;
357         }
358
359         /* signal status */
360         i2c_selectreadbytes(state, TOP_CONTROL, buf, sizeof(buf));
361         dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
362
363 #if 0
364         /* Alternative method to check for a signal */
365         /* using the SNR good/bad interrupts.   */
366         if ((buf[2] & 0x30) == 0x10)
367                 *status |= FE_HAS_SIGNAL;
368 #endif
369
370         /* sync status */
371         if ((buf[2] & 0x03) == 0x01) {
372                 *status |= FE_HAS_SYNC;
373         }
374
375         /* FEC error status */
376         if ((buf[2] & 0x0c) == 0x08) {
377                 *status |= FE_HAS_LOCK;
378                 *status |= FE_HAS_VITERBI;
379         }
380
381         /* Carrier Recovery Lock Status Register */
382         i2c_selectreadbytes(state, CARRIER_LOCK, buf, 1);
383         dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
384         switch (state->current_modulation) {
385         case QAM_256:
386         case QAM_64:
387                 /* Need to undestand why there are 3 lock levels here */
388                 if ((buf[0] & 0x07) == 0x07)
389                         *status |= FE_HAS_CARRIER;
390                 break;
391         case VSB_8:
392                 if ((buf[0] & 0x80) == 0x80)
393                         *status |= FE_HAS_CARRIER;
394                 break;
395         default:
396                 printk("KERN_WARNING lgdt3302: %s: Modulation set to unsupported value\n", __FUNCTION__);
397         }
398
399         return 0;
400 }
401
402 static int lgdt3302_read_signal_strength(struct dvb_frontend* fe, u16* strength)
403 {
404         /* not directly available. */
405         return 0;
406 }
407
408 static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
409 {
410 #ifdef SNR_IN_DB
411         /*
412          * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
413          * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
414          * respectively. The following tables are built on these formulas.
415          * The usual definition is SNR = 20 log10(signal/noise)
416          * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
417          *
418          * This table is a an ordered list of noise values computed by the
419          * formula from the spec sheet such that the index into the table
420          * starting at 43 or 45 is the SNR value in db. There are duplicate noise
421          * value entries at the beginning because the SNR varies more than
422          * 1 db for a change of 1 digit in noise at very small values of noise.
423          *
424          * Examples from SNR_EQ table:
425          * noise SNR
426          *   0    43
427          *   1    42
428          *   2    39
429          *   3    37
430          *   4    36
431          *   5    35
432          *   6    34
433          *   7    33
434          *   8    33
435          *   9    32
436          *   10   32
437          *   11   31
438          *   12   31
439          *   13   30
440          */
441
442         static const u32 SNR_EQ[] =
443                 { 1,     2,      2,      2, 3,      3,      4,     4,     5,     7,
444                   9,     11,     13,     17, 21,     26,     33,    41,    52,    65,
445                   81,    102,    129,    162, 204,    257,    323,   406,   511,   644,
446                   810,   1020,   1284,   1616, 2035,   2561,   3224,  4059,  5110,  6433,
447                   8098,  10195,  12835,  16158, 20341,  25608,  32238, 40585, 51094, 64323,
448                   80978, 101945, 128341, 161571, 203406, 256073, 0x40000
449                 };
450
451         static const u32 SNR_PH[] =
452                 { 1,     2,      2,      2,      3,      3,     4,     5,     6,     8,
453                   10,    12,     15,     19,     23,     29, 37,    46,    58,    73,
454                   91,    115,    144,    182,    229,    288, 362,   456,   574,   722,
455                   909,   1144,   1440,   1813,   2282,   2873, 3617,  4553,  5732,  7216,
456                   9084,  11436,  14396,  18124,  22817,  28724,  36161, 45524, 57312, 72151,
457                   90833, 114351, 143960, 181235, 228161, 0x040000
458                 };
459
460         static u8 buf[5];/* read data buffer */
461         static u32 noise;   /* noise value */
462         static u32 snr_db;  /* index into SNR_EQ[] */
463         struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
464
465         /* read both equalizer and pase tracker noise data */
466         i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
467
468         if (state->current_modulation == VSB_8) {
469                 /* Equalizer Mean-Square Error Register for VSB */
470                 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
471
472                 /*
473                  * Look up noise value in table.
474                  * A better search algorithm could be used...
475                  * watch out there are duplicate entries.
476                  */
477                 for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
478                         if (noise < SNR_EQ[snr_db]) {
479                                 *snr = 43 - snr_db;
480                                 break;
481                         }
482                 }
483         } else {
484                 /* Phase Tracker Mean-Square Error Register for QAM */
485                 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
486
487                 /* Look up noise value in table. */
488                 for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
489                         if (noise < SNR_PH[snr_db]) {
490                                 *snr = 45 - snr_db;
491                                 break;
492                         }
493                 }
494         }
495 #else
496         /* Return the raw noise value */
497         static u8 buf[5];/* read data buffer */
498         static u32 noise;   /* noise value */
499         struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
500
501         /* read both equalizer and pase tracker noise data */
502         i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
503
504         if (state->current_modulation == VSB_8) {
505                 /* Equalizer Mean-Square Error Register for VSB */
506                 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
507         } else {
508                 /* Phase Tracker Mean-Square Error Register for QAM */
509                 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
510         }
511
512         /* Small values for noise mean signal is better so invert noise */
513         /* Noise is 19 bit value so discard 3 LSB*/
514         *snr = ~noise>>3;
515 #endif
516
517         dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
518
519         return 0;
520 }
521
522 static int lgdt3302_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
523 {
524         /* I have no idea about this - it may not be needed */
525         fe_tune_settings->min_delay_ms = 500;
526         fe_tune_settings->step_size = 0;
527         fe_tune_settings->max_drift = 0;
528         return 0;
529 }
530
531 static void lgdt3302_release(struct dvb_frontend* fe)
532 {
533         struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
534         kfree(state);
535 }
536
537 static struct dvb_frontend_ops lgdt3302_ops;
538
539 struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config,
540                                      struct i2c_adapter* i2c)
541 {
542         struct lgdt3302_state* state = NULL;
543         u8 buf[1];
544
545         /* Allocate memory for the internal state */
546         state = (struct lgdt3302_state*) kmalloc(sizeof(struct lgdt3302_state), GFP_KERNEL);
547         if (state == NULL)
548                 goto error;
549         memset(state,0,sizeof(*state));
550
551         /* Setup the state */
552         state->config = config;
553         state->i2c = i2c;
554         memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
555         /* Verify communication with demod chip */
556         if (i2c_selectreadbytes(state, 2, buf, 1))
557                 goto error;
558
559         state->current_frequency = -1;
560         state->current_modulation = -1;
561
562         /* Create dvb_frontend */
563         state->frontend.ops = &state->ops;
564         state->frontend.demodulator_priv = state;
565         return &state->frontend;
566
567 error:
568         if (state)
569                 kfree(state);
570         dprintk("%s: ERROR\n",__FUNCTION__);
571         return NULL;
572 }
573
574 static struct dvb_frontend_ops lgdt3302_ops = {
575         .info = {
576                 .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
577                 .type = FE_ATSC,
578                 .frequency_min= 54000000,
579                 .frequency_max= 858000000,
580                 .frequency_stepsize= 62500,
581                 /* Symbol rate is for all VSB modes need to check QAM */
582                 .symbol_rate_min    = 10762000,
583                 .symbol_rate_max    = 10762000,
584                 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
585         },
586         .init                 = lgdt3302_init,
587         .set_frontend         = lgdt3302_set_parameters,
588         .get_frontend         = lgdt3302_get_frontend,
589         .get_tune_settings    = lgdt3302_get_tune_settings,
590         .read_status          = lgdt3302_read_status,
591         .read_ber             = lgdt3302_read_ber,
592         .read_signal_strength = lgdt3302_read_signal_strength,
593         .read_snr             = lgdt3302_read_snr,
594         .read_ucblocks        = lgdt3302_read_ucblocks,
595         .release              = lgdt3302_release,
596 };
597
598 MODULE_DESCRIPTION("LGDT3302 [DViCO FusionHDTV 3 Gold] (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
599 MODULE_AUTHOR("Wilson Michaels");
600 MODULE_LICENSE("GPL");
601
602 EXPORT_SYMBOL(lgdt3302_attach);
603
604 /*
605  * Local variables:
606  * c-basic-offset: 8
607  * compile-command: "make DVB=1"
608  * End:
609  */