aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/lgdt3302.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/lgdt3302.c')
-rw-r--r--drivers/media/dvb/frontends/lgdt3302.c609
1 files changed, 609 insertions, 0 deletions
diff --git a/drivers/media/dvb/frontends/lgdt3302.c b/drivers/media/dvb/frontends/lgdt3302.c
new file mode 100644
index 000000000000..2eea03d218cd
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3302.c
@@ -0,0 +1,609 @@
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, 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
320static 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
328static 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
402static int lgdt3302_read_signal_strength(struct dvb_frontend* fe, u16* strength)
403{
404 /* not directly available. */
405 return 0;
406}
407
408static 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
522static 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
531static void lgdt3302_release(struct dvb_frontend* fe)
532{
533 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
534 kfree(state);
535}
536
537static struct dvb_frontend_ops lgdt3302_ops;
538
539struct 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
567error:
568 if (state)
569 kfree(state);
570 dprintk("%s: ERROR\n",__FUNCTION__);
571 return NULL;
572}
573
574static 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
598MODULE_DESCRIPTION("LGDT3302 [DViCO FusionHDTV 3 Gold] (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
599MODULE_AUTHOR("Wilson Michaels");
600MODULE_LICENSE("GPL");
601
602EXPORT_SYMBOL(lgdt3302_attach);
603
604/*
605 * Local variables:
606 * c-basic-offset: 8
607 * compile-command: "make DVB=1"
608 * End:
609 */