V4L/DVB (3842): Cx88-dvb: use fe_lgh06xf.h
[safe/jmp/linux-2.6] / drivers / media / video / cx88 / cx88-dvb.c
1 /*
2  *
3  * device driver for Conexant 2388x based TV cards
4  * MPEG Transport Stream (DVB) routines
5  *
6  * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
7  * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/device.h>
27 #include <linux/fs.h>
28 #include <linux/kthread.h>
29 #include <linux/file.h>
30 #include <linux/suspend.h>
31
32 #include "cx88.h"
33 #include "dvb-pll.h"
34 #include <media/v4l2-common.h>
35
36 #ifdef HAVE_MT352
37 # include "mt352.h"
38 # include "mt352_priv.h"
39 # ifdef HAVE_VP3054_I2C
40 #  include "cx88-vp3054-i2c.h"
41 # endif
42 #endif
43 #ifdef HAVE_ZL10353
44 # include "zl10353.h"
45 #endif
46 #ifdef HAVE_CX22702
47 # include "cx22702.h"
48 #endif
49 #ifdef HAVE_OR51132
50 # include "or51132.h"
51 #endif
52 #ifdef HAVE_LGDT330X
53 # include "lgdt330x.h"
54 # include "fe_lgh06xf.h"
55 #endif
56 #ifdef HAVE_NXT200X
57 # include "nxt200x.h"
58 #endif
59 #ifdef HAVE_CX24123
60 # include "cx24123.h"
61 #endif
62
63 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
64 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
65 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
66 MODULE_LICENSE("GPL");
67
68 static unsigned int debug = 0;
69 module_param(debug, int, 0644);
70 MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
71
72 #define dprintk(level,fmt, arg...)      if (debug >= level) \
73         printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->core->name , ## arg)
74
75 /* ------------------------------------------------------------------ */
76
77 static int dvb_buf_setup(struct videobuf_queue *q,
78                          unsigned int *count, unsigned int *size)
79 {
80         struct cx8802_dev *dev = q->priv_data;
81
82         dev->ts_packet_size  = 188 * 4;
83         dev->ts_packet_count = 32;
84
85         *size  = dev->ts_packet_size * dev->ts_packet_count;
86         *count = 32;
87         return 0;
88 }
89
90 static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
91                            enum v4l2_field field)
92 {
93         struct cx8802_dev *dev = q->priv_data;
94         return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
95 }
96
97 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
98 {
99         struct cx8802_dev *dev = q->priv_data;
100         cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
101 }
102
103 static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
104 {
105         cx88_free_buffer(q, (struct cx88_buffer*)vb);
106 }
107
108 static struct videobuf_queue_ops dvb_qops = {
109         .buf_setup    = dvb_buf_setup,
110         .buf_prepare  = dvb_buf_prepare,
111         .buf_queue    = dvb_buf_queue,
112         .buf_release  = dvb_buf_release,
113 };
114
115 /* ------------------------------------------------------------------ */
116
117 #if defined(HAVE_MT352) || defined(HAVE_ZL10353)
118 static int zarlink_pll_set(struct dvb_frontend *fe,
119                               struct dvb_frontend_parameters *params,
120                               u8 *pllbuf)
121 {
122         struct cx8802_dev *dev = fe->dvb->priv;
123
124         pllbuf[0] = dev->core->pll_addr << 1;
125         dvb_pll_configure(dev->core->pll_desc, pllbuf + 1,
126                           params->frequency,
127                           params->u.ofdm.bandwidth);
128         return 0;
129 }
130 #endif
131
132 #ifdef HAVE_MT352
133 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
134 {
135         static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x39 };
136         static u8 reset []         = { RESET,      0x80 };
137         static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
138         static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
139         static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
140         static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
141
142         mt352_write(fe, clock_config,   sizeof(clock_config));
143         udelay(200);
144         mt352_write(fe, reset,          sizeof(reset));
145         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
146
147         mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
148         mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
149         mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
150         return 0;
151 }
152
153 static int dvico_dual_demod_init(struct dvb_frontend *fe)
154 {
155         static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x38 };
156         static u8 reset []         = { RESET,      0x80 };
157         static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
158         static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
159         static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
160         static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
161
162         mt352_write(fe, clock_config,   sizeof(clock_config));
163         udelay(200);
164         mt352_write(fe, reset,          sizeof(reset));
165         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
166
167         mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
168         mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
169         mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
170
171         return 0;
172 }
173
174 static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
175 {
176         static u8 clock_config []  = { 0x89, 0x38, 0x39 };
177         static u8 reset []         = { 0x50, 0x80 };
178         static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
179         static u8 agc_cfg []       = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
180                                        0x00, 0xFF, 0x00, 0x40, 0x40 };
181         static u8 dntv_extra[]     = { 0xB5, 0x7A };
182         static u8 capt_range_cfg[] = { 0x75, 0x32 };
183
184         mt352_write(fe, clock_config,   sizeof(clock_config));
185         udelay(2000);
186         mt352_write(fe, reset,          sizeof(reset));
187         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
188
189         mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
190         udelay(2000);
191         mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
192         mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
193
194         return 0;
195 }
196
197 static struct mt352_config dvico_fusionhdtv = {
198         .demod_address = 0x0F,
199         .demod_init    = dvico_fusionhdtv_demod_init,
200         .pll_set       = zarlink_pll_set,
201 };
202
203 static struct mt352_config dntv_live_dvbt_config = {
204         .demod_address = 0x0f,
205         .demod_init    = dntv_live_dvbt_demod_init,
206         .pll_set       = zarlink_pll_set,
207 };
208
209 static struct mt352_config dvico_fusionhdtv_dual = {
210         .demod_address = 0x0F,
211         .demod_init    = dvico_dual_demod_init,
212         .pll_set       = zarlink_pll_set,
213 };
214
215 #ifdef HAVE_VP3054_I2C
216 static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
217 {
218         static u8 clock_config []  = { 0x89, 0x38, 0x38 };
219         static u8 reset []         = { 0x50, 0x80 };
220         static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
221         static u8 agc_cfg []       = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
222                                        0x00, 0xFF, 0x00, 0x40, 0x40 };
223         static u8 dntv_extra[]     = { 0xB5, 0x7A };
224         static u8 capt_range_cfg[] = { 0x75, 0x32 };
225
226         mt352_write(fe, clock_config,   sizeof(clock_config));
227         udelay(2000);
228         mt352_write(fe, reset,          sizeof(reset));
229         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
230
231         mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
232         udelay(2000);
233         mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
234         mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
235
236         return 0;
237 }
238
239 static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
240 {
241         struct cx8802_dev *dev= fe->dvb->priv;
242
243         /* this message is to set up ATC and ALC */
244         static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
245         struct i2c_msg msg =
246                 { .addr = dev->core->pll_addr, .flags = 0,
247                   .buf = fmd1216_init, .len = sizeof(fmd1216_init) };
248         int err;
249
250         if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
251                 if (err < 0)
252                         return err;
253                 else
254                         return -EREMOTEIO;
255         }
256
257         return 0;
258 }
259
260 static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe,
261                                       struct dvb_frontend_parameters* params,
262                                       u8* pllbuf)
263 {
264         struct cx8802_dev *dev= fe->dvb->priv;
265         struct i2c_msg msg =
266                 { .addr = dev->core->pll_addr, .flags = 0,
267                   .buf = pllbuf+1, .len = 4 };
268         int err;
269
270         /* Switch PLL to DVB mode */
271         err = philips_fmd1216_pll_init(fe);
272         if (err)
273                 return err;
274
275         /* Tune PLL */
276         pllbuf[0] = dev->core->pll_addr << 1;
277         dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
278                           params->frequency,
279                           params->u.ofdm.bandwidth);
280         if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
281                 printk(KERN_WARNING "cx88-dvb: %s error "
282                            "(addr %02x <- %02x, err = %i)\n",
283                            __FUNCTION__, pllbuf[0], pllbuf[1], err);
284                 if (err < 0)
285                         return err;
286                 else
287                         return -EREMOTEIO;
288         }
289
290         return 0;
291 }
292
293 static struct mt352_config dntv_live_dvbt_pro_config = {
294         .demod_address = 0x0f,
295         .no_tuner      = 1,
296         .demod_init    = dntv_live_dvbt_pro_demod_init,
297         .pll_set       = dntv_live_dvbt_pro_pll_set,
298 };
299 #endif
300 #endif
301
302 #ifdef HAVE_ZL10353
303 static int dvico_hybrid_tune_pll(struct dvb_frontend *fe,
304                                  struct dvb_frontend_parameters *params,
305                                  u8 *pllbuf)
306 {
307         struct cx8802_dev *dev= fe->dvb->priv;
308         struct i2c_msg msg =
309                 { .addr = dev->core->pll_addr, .flags = 0,
310                   .buf = pllbuf + 1, .len = 4 };
311         int err;
312
313         pllbuf[0] = dev->core->pll_addr << 1;
314         dvb_pll_configure(dev->core->pll_desc, pllbuf + 1,
315                           params->frequency,
316                           params->u.ofdm.bandwidth);
317
318         if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
319                 printk(KERN_WARNING "cx88-dvb: %s error "
320                            "(addr %02x <- %02x, err = %i)\n",
321                            __FUNCTION__, pllbuf[0], pllbuf[1], err);
322                 if (err < 0)
323                         return err;
324                 else
325                         return -EREMOTEIO;
326         }
327
328         return 0;
329 }
330
331 static struct zl10353_config dvico_fusionhdtv_hybrid = {
332         .demod_address = 0x0F,
333         .pll_set       = dvico_hybrid_tune_pll,
334 };
335
336 static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
337         .demod_address = 0x0F,
338         .pll_set       = zarlink_pll_set,
339 };
340 #endif
341
342 #ifdef HAVE_CX22702
343 static struct cx22702_config connexant_refboard_config = {
344         .demod_address = 0x43,
345         .output_mode   = CX22702_SERIAL_OUTPUT,
346         .pll_address   = 0x60,
347         .pll_desc      = &dvb_pll_thomson_dtt7579,
348 };
349
350 static struct cx22702_config hauppauge_novat_config = {
351         .demod_address = 0x43,
352         .output_mode   = CX22702_SERIAL_OUTPUT,
353         .pll_address   = 0x61,
354         .pll_desc      = &dvb_pll_thomson_dtt759x,
355 };
356 static struct cx22702_config hauppauge_hvr1100_config = {
357         .demod_address = 0x63,
358         .output_mode   = CX22702_SERIAL_OUTPUT,
359         .pll_address   = 0x61,
360         .pll_desc      = &dvb_pll_fmd1216me,
361 };
362 #endif
363
364 #ifdef HAVE_OR51132
365 static int or51132_set_ts_param(struct dvb_frontend* fe,
366                                 int is_punctured)
367 {
368         struct cx8802_dev *dev= fe->dvb->priv;
369         dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
370         return 0;
371 }
372
373 static struct or51132_config pchdtv_hd3000 = {
374         .demod_address    = 0x15,
375         .pll_address      = 0x61,
376         .pll_desc         = &dvb_pll_thomson_dtt761x,
377         .set_ts_params    = or51132_set_ts_param,
378 };
379 #endif
380
381 #ifdef HAVE_LGDT330X
382 static int lgdt3302_pll_set(struct dvb_frontend* fe,
383                             struct dvb_frontend_parameters* params)
384 {
385         /* FIXME make this routine use the tuner-simple code.
386          * It could probably be shared with a number of ATSC
387          * frontends. Many share the same tuner with analog TV. */
388
389         struct cx8802_dev *dev= fe->dvb->priv;
390         struct cx88_core *core = dev->core;
391         u8 buf[4];
392         struct i2c_msg msg =
393                 { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 };
394         int err;
395
396         dvb_pll_configure(core->pll_desc, buf, params->frequency, 0);
397         dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
398                         __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
399         if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) {
400                 printk(KERN_WARNING "cx88-dvb: %s error "
401                            "(addr %02x <- %02x, err = %i)\n",
402                            __FUNCTION__, buf[0], buf[1], err);
403                 if (err < 0)
404                         return err;
405                 else
406                         return -EREMOTEIO;
407         }
408         return 0;
409 }
410
411 static int lgdt3303_pll_set(struct dvb_frontend* fe,
412                             struct dvb_frontend_parameters* params)
413 {
414         struct cx8802_dev *dev= fe->dvb->priv;
415         struct cx88_core *core = dev->core;
416
417         /* Put the analog decoder in standby to keep it quiet */
418         cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
419
420         return lg_h06xf_pll_set(fe, &core->i2c_adap, params);
421 }
422
423 static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
424 {
425         struct cx8802_dev *dev= fe->dvb->priv;
426         struct cx88_core *core = dev->core;
427
428         dprintk(1, "%s: index = %d\n", __FUNCTION__, index);
429         if (index == 0)
430                 cx_clear(MO_GP0_IO, 8);
431         else
432                 cx_set(MO_GP0_IO, 8);
433         return 0;
434 }
435
436 static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
437 {
438         struct cx8802_dev *dev= fe->dvb->priv;
439         if (is_punctured)
440                 dev->ts_gen_cntrl |= 0x04;
441         else
442                 dev->ts_gen_cntrl &= ~0x04;
443         return 0;
444 }
445
446 static struct lgdt330x_config fusionhdtv_3_gold = {
447         .demod_address    = 0x0e,
448         .demod_chip       = LGDT3302,
449         .serial_mpeg      = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
450         .pll_set          = lgdt3302_pll_set,
451         .set_ts_params    = lgdt330x_set_ts_param,
452 };
453
454 static struct lgdt330x_config fusionhdtv_5_gold = {
455         .demod_address    = 0x0e,
456         .demod_chip       = LGDT3303,
457         .serial_mpeg      = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
458         .pll_set          = lgdt3303_pll_set,
459         .set_ts_params    = lgdt330x_set_ts_param,
460 };
461
462 static struct lgdt330x_config pchdtv_hd5500 = {
463         .demod_address    = 0x59,
464         .demod_chip       = LGDT3303,
465         .serial_mpeg      = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
466         .pll_set          = lgdt3303_pll_set,
467         .set_ts_params    = lgdt330x_set_ts_param,
468 };
469 #endif
470
471 #ifdef HAVE_NXT200X
472 static int nxt200x_set_ts_param(struct dvb_frontend* fe,
473                                 int is_punctured)
474 {
475         struct cx8802_dev *dev= fe->dvb->priv;
476         dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
477         return 0;
478 }
479
480 static int nxt200x_set_pll_input(u8* buf, int input)
481 {
482         if (input)
483                 buf[3] |= 0x08;
484         else
485                 buf[3] &= ~0x08;
486         return 0;
487 }
488
489 static struct nxt200x_config ati_hdtvwonder = {
490         .demod_address    = 0x0a,
491         .pll_address      = 0x61,
492         .pll_desc         = &dvb_pll_tuv1236d,
493         .set_pll_input    = nxt200x_set_pll_input,
494         .set_ts_params    = nxt200x_set_ts_param,
495 };
496 #endif
497
498 #ifdef HAVE_CX24123
499 static int cx24123_set_ts_param(struct dvb_frontend* fe,
500         int is_punctured)
501 {
502         struct cx8802_dev *dev= fe->dvb->priv;
503         dev->ts_gen_cntrl = 0x2;
504         return 0;
505 }
506
507 static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on)
508 {
509         struct cx8802_dev *dev= fe->dvb->priv;
510         struct cx88_core *core = dev->core;
511
512         if (on)
513                 cx_write(MO_GP0_IO, 0x000006f9);
514         else
515                 cx_write(MO_GP0_IO, 0x000006fB);
516 }
517
518 static struct cx24123_config hauppauge_novas_config = {
519         .demod_address          = 0x55,
520         .use_isl6421            = 1,
521         .set_ts_params          = cx24123_set_ts_param,
522 };
523
524 static struct cx24123_config kworld_dvbs_100_config = {
525         .demod_address          = 0x15,
526         .use_isl6421            = 0,
527         .set_ts_params          = cx24123_set_ts_param,
528         .enable_lnb_voltage     = cx24123_enable_lnb_voltage,
529 };
530 #endif
531
532 static int dvb_register(struct cx8802_dev *dev)
533 {
534         /* init struct videobuf_dvb */
535         dev->dvb.name = dev->core->name;
536         dev->ts_gen_cntrl = 0x0c;
537
538         /* init frontend */
539         switch (dev->core->board) {
540 #ifdef HAVE_CX22702
541         case CX88_BOARD_HAUPPAUGE_DVB_T1:
542                 dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
543                                                    &dev->core->i2c_adap);
544                 break;
545         case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
546         case CX88_BOARD_CONEXANT_DVB_T1:
547         case CX88_BOARD_KWORLD_DVB_T_CX22702:
548         case CX88_BOARD_WINFAST_DTV1000:
549                 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
550                                                    &dev->core->i2c_adap);
551                 break;
552         case CX88_BOARD_HAUPPAUGE_HVR1100:
553         case CX88_BOARD_HAUPPAUGE_HVR1100LP:
554                 dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config,
555                                                    &dev->core->i2c_adap);
556                 break;
557 #endif
558 #if defined(HAVE_MT352) || defined(HAVE_ZL10353)
559         case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
560                 dev->core->pll_addr = 0x60;
561                 dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
562 #ifdef HAVE_MT352
563                 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
564                                                  &dev->core->i2c_adap);
565                 if (dev->dvb.frontend != NULL)
566                         break;
567 #endif
568 #ifdef HAVE_ZL10353
569                 /* ZL10353 replaces MT352 on later cards */
570                 dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1,
571                                                    &dev->core->i2c_adap);
572 #endif
573                 break;
574 #endif /* HAVE_MT352 || HAVE_ZL10353 */
575 #ifdef HAVE_MT352
576         case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
577                 dev->core->pll_addr = 0x61;
578                 dev->core->pll_desc = &dvb_pll_lg_z201;
579                 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
580                                                  &dev->core->i2c_adap);
581                 break;
582         case CX88_BOARD_KWORLD_DVB_T:
583         case CX88_BOARD_DNTV_LIVE_DVB_T:
584         case CX88_BOARD_ADSTECH_DVB_T_PCI:
585                 dev->core->pll_addr = 0x61;
586                 dev->core->pll_desc = &dvb_pll_unknown_1;
587                 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
588                                                  &dev->core->i2c_adap);
589                 break;
590         case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
591 #ifdef HAVE_VP3054_I2C
592                 dev->core->pll_addr = 0x61;
593                 dev->core->pll_desc = &dvb_pll_fmd1216me;
594                 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config,
595                         &((struct vp3054_i2c_state *)dev->card_priv)->adap);
596 #else
597                 printk("%s: built without vp3054 support\n", dev->core->name);
598 #endif
599                 break;
600         case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
601                 /* The tin box says DEE1601, but it seems to be DTT7579
602                  * compatible, with a slightly different MT352 AGC gain. */
603                 dev->core->pll_addr = 0x61;
604                 dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
605                 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual,
606                                                  &dev->core->i2c_adap);
607                 break;
608 #endif
609 #ifdef HAVE_ZL10353
610         case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
611                 dev->core->pll_addr = 0x61;
612                 dev->core->pll_desc = &dvb_pll_thomson_fe6600;
613                 dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid,
614                                                    &dev->core->i2c_adap);
615                 break;
616 #endif
617 #ifdef HAVE_OR51132
618         case CX88_BOARD_PCHDTV_HD3000:
619                 dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
620                                                  &dev->core->i2c_adap);
621                 break;
622 #endif
623 #ifdef HAVE_LGDT330X
624         case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
625                 dev->ts_gen_cntrl = 0x08;
626                 {
627                 /* Do a hardware reset of chip before using it. */
628                 struct cx88_core *core = dev->core;
629
630                 cx_clear(MO_GP0_IO, 1);
631                 mdelay(100);
632                 cx_set(MO_GP0_IO, 1);
633                 mdelay(200);
634
635                 /* Select RF connector callback */
636                 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
637                 dev->core->pll_addr = 0x61;
638                 dev->core->pll_desc = &dvb_pll_microtune_4042;
639                 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
640                                                     &dev->core->i2c_adap);
641                 }
642                 break;
643         case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
644                 dev->ts_gen_cntrl = 0x08;
645                 {
646                 /* Do a hardware reset of chip before using it. */
647                 struct cx88_core *core = dev->core;
648
649                 cx_clear(MO_GP0_IO, 1);
650                 mdelay(100);
651                 cx_set(MO_GP0_IO, 9);
652                 mdelay(200);
653                 dev->core->pll_addr = 0x61;
654                 dev->core->pll_desc = &dvb_pll_thomson_dtt761x;
655                 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
656                                                     &dev->core->i2c_adap);
657                 }
658                 break;
659         case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
660                 dev->ts_gen_cntrl = 0x08;
661                 {
662                 /* Do a hardware reset of chip before using it. */
663                 struct cx88_core *core = dev->core;
664
665                 cx_clear(MO_GP0_IO, 1);
666                 mdelay(100);
667                 cx_set(MO_GP0_IO, 1);
668                 mdelay(200);
669                 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold,
670                                                     &dev->core->i2c_adap);
671                 }
672                 break;
673         case CX88_BOARD_PCHDTV_HD5500:
674                 dev->ts_gen_cntrl = 0x08;
675                 {
676                 /* Do a hardware reset of chip before using it. */
677                 struct cx88_core *core = dev->core;
678
679                 cx_clear(MO_GP0_IO, 1);
680                 mdelay(100);
681                 cx_set(MO_GP0_IO, 1);
682                 mdelay(200);
683                 dev->dvb.frontend = lgdt330x_attach(&pchdtv_hd5500,
684                                                     &dev->core->i2c_adap);
685                 }
686                 break;
687 #endif
688 #ifdef HAVE_NXT200X
689         case CX88_BOARD_ATI_HDTVWONDER:
690                 dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder,
691                                                  &dev->core->i2c_adap);
692                 break;
693 #endif
694 #ifdef HAVE_CX24123
695         case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
696         case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
697                 dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config,
698                         &dev->core->i2c_adap);
699                 break;
700         case CX88_BOARD_KWORLD_DVBS_100:
701                 dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config,
702                         &dev->core->i2c_adap);
703                 break;
704 #endif
705         default:
706                 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
707                        dev->core->name);
708                 break;
709         }
710         if (NULL == dev->dvb.frontend) {
711                 printk("%s: frontend initialization failed\n",dev->core->name);
712                 return -1;
713         }
714
715         if (dev->core->pll_desc) {
716                 dev->dvb.frontend->ops->info.frequency_min = dev->core->pll_desc->min;
717                 dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max;
718         }
719
720         /* Put the analog decoder in standby to keep it quiet */
721         cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
722
723         /* register everything */
724         return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev);
725 }
726
727 /* ----------------------------------------------------------- */
728
729 static int __devinit dvb_probe(struct pci_dev *pci_dev,
730                                const struct pci_device_id *pci_id)
731 {
732         struct cx8802_dev *dev;
733         struct cx88_core  *core;
734         int err;
735
736         /* general setup */
737         core = cx88_core_get(pci_dev);
738         if (NULL == core)
739                 return -EINVAL;
740
741         err = -ENODEV;
742         if (!cx88_boards[core->board].dvb)
743                 goto fail_core;
744
745         err = -ENOMEM;
746         dev = kzalloc(sizeof(*dev),GFP_KERNEL);
747         if (NULL == dev)
748                 goto fail_core;
749         dev->pci = pci_dev;
750         dev->core = core;
751
752         err = cx8802_init_common(dev);
753         if (0 != err)
754                 goto fail_free;
755
756 #ifdef HAVE_VP3054_I2C
757         err = vp3054_i2c_probe(dev);
758         if (0 != err)
759                 goto fail_free;
760 #endif
761
762         /* dvb stuff */
763         printk("%s/2: cx2388x based dvb card\n", core->name);
764         videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
765                             dev->pci, &dev->slock,
766                             V4L2_BUF_TYPE_VIDEO_CAPTURE,
767                             V4L2_FIELD_TOP,
768                             sizeof(struct cx88_buffer),
769                             dev);
770         err = dvb_register(dev);
771         if (0 != err)
772                 goto fail_fini;
773
774         /* Maintain a reference to cx88-video can query the 8802 device. */
775         core->dvbdev = dev;
776         return 0;
777
778  fail_fini:
779         cx8802_fini_common(dev);
780  fail_free:
781         kfree(dev);
782  fail_core:
783         cx88_core_put(core,pci_dev);
784         return err;
785 }
786
787 static void __devexit dvb_remove(struct pci_dev *pci_dev)
788 {
789         struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
790
791         /* Destroy any 8802 reference. */
792         dev->core->dvbdev = NULL;
793
794         /* dvb */
795         videobuf_dvb_unregister(&dev->dvb);
796
797 #ifdef HAVE_VP3054_I2C
798         vp3054_i2c_remove(dev);
799 #endif
800
801         /* common */
802         cx8802_fini_common(dev);
803         cx88_core_put(dev->core,dev->pci);
804         kfree(dev);
805 }
806
807 static struct pci_device_id cx8802_pci_tbl[] = {
808         {
809                 .vendor       = 0x14f1,
810                 .device       = 0x8802,
811                 .subvendor    = PCI_ANY_ID,
812                 .subdevice    = PCI_ANY_ID,
813         },{
814                 /* --- end of list --- */
815         }
816 };
817 MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
818
819 static struct pci_driver dvb_pci_driver = {
820         .name     = "cx88-dvb",
821         .id_table = cx8802_pci_tbl,
822         .probe    = dvb_probe,
823         .remove   = __devexit_p(dvb_remove),
824         .suspend  = cx8802_suspend_common,
825         .resume   = cx8802_resume_common,
826 };
827
828 static int dvb_init(void)
829 {
830         printk(KERN_INFO "cx2388x dvb driver version %d.%d.%d loaded\n",
831                (CX88_VERSION_CODE >> 16) & 0xff,
832                (CX88_VERSION_CODE >>  8) & 0xff,
833                CX88_VERSION_CODE & 0xff);
834 #ifdef SNAPSHOT
835         printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
836                SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
837 #endif
838         return pci_register_driver(&dvb_pci_driver);
839 }
840
841 static void dvb_fini(void)
842 {
843         pci_unregister_driver(&dvb_pci_driver);
844 }
845
846 module_init(dvb_init);
847 module_exit(dvb_fini);
848
849 /*
850  * Local variables:
851  * c-basic-offset: 8
852  * compile-command: "make DVB=1"
853  * End:
854  */