]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/cx88/cx88-dvb.c
V4L/DVB (9222): S2API: Add Multiple-frontend on a single adapter support.
[linux-2.6-omap-h63xx.git] / 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 #include "mt352.h"
37 #include "mt352_priv.h"
38 #include "cx88-vp3054-i2c.h"
39 #include "zl10353.h"
40 #include "cx22702.h"
41 #include "or51132.h"
42 #include "lgdt330x.h"
43 #include "s5h1409.h"
44 #include "xc5000.h"
45 #include "nxt200x.h"
46 #include "cx24123.h"
47 #include "isl6421.h"
48 #include "tuner-simple.h"
49 #include "tda9887.h"
50 #include "s5h1411.h"
51 #include "stv0299.h"
52 #include "z0194a.h"
53 #include "stv0288.h"
54 #include "stb6000.h"
55 #include "cx24116.h"
56
57 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
58 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
59 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
60 MODULE_LICENSE("GPL");
61
62 static unsigned int debug;
63 module_param(debug, int, 0644);
64 MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
65
66 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
67
68 #define dprintk(level,fmt, arg...)      if (debug >= level) \
69         printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
70
71 /* ------------------------------------------------------------------ */
72
73 static int dvb_buf_setup(struct videobuf_queue *q,
74                          unsigned int *count, unsigned int *size)
75 {
76         struct cx8802_dev *dev = q->priv_data;
77
78         dev->ts_packet_size  = 188 * 4;
79         dev->ts_packet_count = 32;
80
81         *size  = dev->ts_packet_size * dev->ts_packet_count;
82         *count = 32;
83         return 0;
84 }
85
86 static int dvb_buf_prepare(struct videobuf_queue *q,
87                            struct videobuf_buffer *vb, enum v4l2_field field)
88 {
89         struct cx8802_dev *dev = q->priv_data;
90         return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
91 }
92
93 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
94 {
95         struct cx8802_dev *dev = q->priv_data;
96         cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
97 }
98
99 static void dvb_buf_release(struct videobuf_queue *q,
100                             struct videobuf_buffer *vb)
101 {
102         cx88_free_buffer(q, (struct cx88_buffer*)vb);
103 }
104
105 static struct videobuf_queue_ops dvb_qops = {
106         .buf_setup    = dvb_buf_setup,
107         .buf_prepare  = dvb_buf_prepare,
108         .buf_queue    = dvb_buf_queue,
109         .buf_release  = dvb_buf_release,
110 };
111
112 /* ------------------------------------------------------------------ */
113
114 static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
115 {
116         struct cx8802_dev *dev= fe->dvb->priv;
117         struct cx8802_driver *drv = NULL;
118         int ret = 0;
119         int fe_id;
120
121         fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
122         if (!fe_id) {
123                 printk(KERN_ERR "%s() No frontend found\n", __FUNCTION__);
124                 return -EINVAL;
125         }
126
127
128         drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
129         if (drv) {
130                 if (acquire){
131                         dev->frontends.active_fe_id = fe_id;
132                         ret = drv->request_acquire(drv);
133                 } else {
134                         ret = drv->request_release(drv);
135                         dev->frontends.active_fe_id = 0;
136                 }
137         }
138
139         return ret;
140 }
141
142 /* ------------------------------------------------------------------ */
143
144 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
145 {
146         static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x39 };
147         static u8 reset []         = { RESET,      0x80 };
148         static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
149         static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
150         static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
151         static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
152
153         mt352_write(fe, clock_config,   sizeof(clock_config));
154         udelay(200);
155         mt352_write(fe, reset,          sizeof(reset));
156         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
157
158         mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
159         mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
160         mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
161         return 0;
162 }
163
164 static int dvico_dual_demod_init(struct dvb_frontend *fe)
165 {
166         static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x38 };
167         static u8 reset []         = { RESET,      0x80 };
168         static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
169         static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
170         static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
171         static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
172
173         mt352_write(fe, clock_config,   sizeof(clock_config));
174         udelay(200);
175         mt352_write(fe, reset,          sizeof(reset));
176         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
177
178         mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
179         mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
180         mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
181
182         return 0;
183 }
184
185 static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
186 {
187         static u8 clock_config []  = { 0x89, 0x38, 0x39 };
188         static u8 reset []         = { 0x50, 0x80 };
189         static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
190         static u8 agc_cfg []       = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
191                                        0x00, 0xFF, 0x00, 0x40, 0x40 };
192         static u8 dntv_extra[]     = { 0xB5, 0x7A };
193         static u8 capt_range_cfg[] = { 0x75, 0x32 };
194
195         mt352_write(fe, clock_config,   sizeof(clock_config));
196         udelay(2000);
197         mt352_write(fe, reset,          sizeof(reset));
198         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
199
200         mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
201         udelay(2000);
202         mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
203         mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
204
205         return 0;
206 }
207
208 static struct mt352_config dvico_fusionhdtv = {
209         .demod_address = 0x0f,
210         .demod_init    = dvico_fusionhdtv_demod_init,
211 };
212
213 static struct mt352_config dntv_live_dvbt_config = {
214         .demod_address = 0x0f,
215         .demod_init    = dntv_live_dvbt_demod_init,
216 };
217
218 static struct mt352_config dvico_fusionhdtv_dual = {
219         .demod_address = 0x0f,
220         .demod_init    = dvico_dual_demod_init,
221 };
222
223 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
224 static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
225 {
226         static u8 clock_config []  = { 0x89, 0x38, 0x38 };
227         static u8 reset []         = { 0x50, 0x80 };
228         static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
229         static u8 agc_cfg []       = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
230                                        0x00, 0xFF, 0x00, 0x40, 0x40 };
231         static u8 dntv_extra[]     = { 0xB5, 0x7A };
232         static u8 capt_range_cfg[] = { 0x75, 0x32 };
233
234         mt352_write(fe, clock_config,   sizeof(clock_config));
235         udelay(2000);
236         mt352_write(fe, reset,          sizeof(reset));
237         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
238
239         mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
240         udelay(2000);
241         mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
242         mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
243
244         return 0;
245 }
246
247 static struct mt352_config dntv_live_dvbt_pro_config = {
248         .demod_address = 0x0f,
249         .no_tuner      = 1,
250         .demod_init    = dntv_live_dvbt_pro_demod_init,
251 };
252 #endif
253
254 static struct zl10353_config dvico_fusionhdtv_hybrid = {
255         .demod_address = 0x0f,
256         .no_tuner      = 1,
257 };
258
259 static struct zl10353_config dvico_fusionhdtv_xc3028 = {
260         .demod_address = 0x0f,
261         .if2           = 45600,
262         .no_tuner      = 1,
263 };
264
265 static struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
266         .demod_address = 0x0f,
267         .if2 = 4560,
268         .no_tuner = 1,
269         .demod_init = dvico_fusionhdtv_demod_init,
270 };
271
272 static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
273         .demod_address = 0x0f,
274 };
275
276 static struct cx22702_config connexant_refboard_config = {
277         .demod_address = 0x43,
278         .output_mode   = CX22702_SERIAL_OUTPUT,
279 };
280
281 static struct cx22702_config hauppauge_hvr_config = {
282         .demod_address = 0x63,
283         .output_mode   = CX22702_SERIAL_OUTPUT,
284 };
285
286 static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
287 {
288         struct cx8802_dev *dev= fe->dvb->priv;
289         dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
290         return 0;
291 }
292
293 static struct or51132_config pchdtv_hd3000 = {
294         .demod_address = 0x15,
295         .set_ts_params = or51132_set_ts_param,
296 };
297
298 static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
299 {
300         struct cx8802_dev *dev= fe->dvb->priv;
301         struct cx88_core *core = dev->core;
302
303         dprintk(1, "%s: index = %d\n", __func__, index);
304         if (index == 0)
305                 cx_clear(MO_GP0_IO, 8);
306         else
307                 cx_set(MO_GP0_IO, 8);
308         return 0;
309 }
310
311 static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
312 {
313         struct cx8802_dev *dev= fe->dvb->priv;
314         if (is_punctured)
315                 dev->ts_gen_cntrl |= 0x04;
316         else
317                 dev->ts_gen_cntrl &= ~0x04;
318         return 0;
319 }
320
321 static struct lgdt330x_config fusionhdtv_3_gold = {
322         .demod_address = 0x0e,
323         .demod_chip    = LGDT3302,
324         .serial_mpeg   = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
325         .set_ts_params = lgdt330x_set_ts_param,
326 };
327
328 static struct lgdt330x_config fusionhdtv_5_gold = {
329         .demod_address = 0x0e,
330         .demod_chip    = LGDT3303,
331         .serial_mpeg   = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
332         .set_ts_params = lgdt330x_set_ts_param,
333 };
334
335 static struct lgdt330x_config pchdtv_hd5500 = {
336         .demod_address = 0x59,
337         .demod_chip    = LGDT3303,
338         .serial_mpeg   = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
339         .set_ts_params = lgdt330x_set_ts_param,
340 };
341
342 static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
343 {
344         struct cx8802_dev *dev= fe->dvb->priv;
345         dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
346         return 0;
347 }
348
349 static struct nxt200x_config ati_hdtvwonder = {
350         .demod_address = 0x0a,
351         .set_ts_params = nxt200x_set_ts_param,
352 };
353
354 static int cx24123_set_ts_param(struct dvb_frontend* fe,
355         int is_punctured)
356 {
357         struct cx8802_dev *dev= fe->dvb->priv;
358         dev->ts_gen_cntrl = 0x02;
359         return 0;
360 }
361
362 static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
363                                        fe_sec_voltage_t voltage)
364 {
365         struct cx8802_dev *dev= fe->dvb->priv;
366         struct cx88_core *core = dev->core;
367
368         if (voltage == SEC_VOLTAGE_OFF)
369                 cx_write(MO_GP0_IO, 0x000006fb);
370         else
371                 cx_write(MO_GP0_IO, 0x000006f9);
372
373         if (core->prev_set_voltage)
374                 return core->prev_set_voltage(fe, voltage);
375         return 0;
376 }
377
378 static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
379                                       fe_sec_voltage_t voltage)
380 {
381         struct cx8802_dev *dev= fe->dvb->priv;
382         struct cx88_core *core = dev->core;
383
384         if (voltage == SEC_VOLTAGE_OFF) {
385                 dprintk(1,"LNB Voltage OFF\n");
386                 cx_write(MO_GP0_IO, 0x0000efff);
387         }
388
389         if (core->prev_set_voltage)
390                 return core->prev_set_voltage(fe, voltage);
391         return 0;
392 }
393
394 static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
395                                       fe_sec_voltage_t voltage)
396 {
397         struct cx8802_dev *dev= fe->dvb->priv;
398         struct cx88_core *core = dev->core;
399
400         switch (voltage) {
401                 case SEC_VOLTAGE_13:
402                         printk("LNB Voltage SEC_VOLTAGE_13\n");
403                         cx_write(MO_GP0_IO, 0x00006040);
404                         break;
405                 case SEC_VOLTAGE_18:
406                         printk("LNB Voltage SEC_VOLTAGE_18\n");
407                         cx_write(MO_GP0_IO, 0x00006060);
408                         break;
409                 case SEC_VOLTAGE_OFF:
410                         printk("LNB Voltage SEC_VOLTAGE_off\n");
411                         break;
412         }
413
414         if (core->prev_set_voltage)
415                 return core->prev_set_voltage(fe, voltage);
416         return 0;
417 }
418
419 static struct cx24123_config geniatech_dvbs_config = {
420         .demod_address = 0x55,
421         .set_ts_params = cx24123_set_ts_param,
422 };
423
424 static struct cx24123_config hauppauge_novas_config = {
425         .demod_address = 0x55,
426         .set_ts_params = cx24123_set_ts_param,
427 };
428
429 static struct cx24123_config kworld_dvbs_100_config = {
430         .demod_address = 0x15,
431         .set_ts_params = cx24123_set_ts_param,
432         .lnb_polarity  = 1,
433 };
434
435 static struct s5h1409_config pinnacle_pctv_hd_800i_config = {
436         .demod_address = 0x32 >> 1,
437         .output_mode   = S5H1409_PARALLEL_OUTPUT,
438         .gpio          = S5H1409_GPIO_ON,
439         .qam_if        = 44000,
440         .inversion     = S5H1409_INVERSION_OFF,
441         .status_mode   = S5H1409_DEMODLOCKING,
442         .mpeg_timing   = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
443 };
444
445 static struct s5h1409_config dvico_hdtv5_pci_nano_config = {
446         .demod_address = 0x32 >> 1,
447         .output_mode   = S5H1409_SERIAL_OUTPUT,
448         .gpio          = S5H1409_GPIO_OFF,
449         .inversion     = S5H1409_INVERSION_OFF,
450         .status_mode   = S5H1409_DEMODLOCKING,
451         .mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
452 };
453
454 static struct s5h1409_config kworld_atsc_120_config = {
455         .demod_address = 0x32 >> 1,
456         .output_mode   = S5H1409_SERIAL_OUTPUT,
457         .gpio          = S5H1409_GPIO_OFF,
458         .inversion     = S5H1409_INVERSION_OFF,
459         .status_mode   = S5H1409_DEMODLOCKING,
460         .mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
461 };
462
463 static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
464         .i2c_address    = 0x64,
465         .if_khz         = 5380,
466 };
467
468 static struct zl10353_config cx88_pinnacle_hybrid_pctv = {
469         .demod_address = (0x1e >> 1),
470         .no_tuner      = 1,
471         .if2           = 45600,
472 };
473
474 static struct zl10353_config cx88_geniatech_x8000_mt = {
475        .demod_address = (0x1e >> 1),
476        .no_tuner = 1,
477 };
478
479 static struct s5h1411_config dvico_fusionhdtv7_config = {
480         .output_mode   = S5H1411_SERIAL_OUTPUT,
481         .gpio          = S5H1411_GPIO_ON,
482         .mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
483         .qam_if        = S5H1411_IF_44000,
484         .vsb_if        = S5H1411_IF_44000,
485         .inversion     = S5H1411_INVERSION_OFF,
486         .status_mode   = S5H1411_DEMODLOCKING
487 };
488
489 static struct xc5000_config dvico_fusionhdtv7_tuner_config = {
490         .i2c_address    = 0xc2 >> 1,
491         .if_khz         = 5380,
492 };
493
494 static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
495 {
496         struct dvb_frontend *fe;
497         struct videobuf_dvb_frontend *fe0 = NULL;
498         struct xc2028_ctrl ctl;
499         struct xc2028_config cfg = {
500                 .i2c_adap  = &dev->core->i2c_adap,
501                 .i2c_addr  = addr,
502                 .ctrl      = &ctl,
503         };
504
505 /* Get the first frontend */
506         fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
507         if (!fe0)
508                 return -EINVAL;
509
510         if (!fe0->dvb.frontend) {
511                 printk(KERN_ERR "%s/2: dvb frontend not attached. "
512                                 "Can't attach xc3028\n",
513                        dev->core->name);
514                 return -EINVAL;
515         }
516
517         /*
518          * Some xc3028 devices may be hidden by an I2C gate. This is known
519          * to happen with some s5h1409-based devices.
520          * Now that I2C gate is open, sets up xc3028 configuration
521          */
522         cx88_setup_xc3028(dev->core, &ctl);
523
524         fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
525         if (!fe) {
526                 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
527                        dev->core->name);
528                 dvb_frontend_detach(fe0->dvb.frontend);
529                 dvb_unregister_frontend(fe0->dvb.frontend);
530                 fe0->dvb.frontend = NULL;
531                 return -EINVAL;
532         }
533
534         printk(KERN_INFO "%s/2: xc3028 attached\n",
535                dev->core->name);
536
537         return 0;
538 }
539
540 static int cx24116_set_ts_param(struct dvb_frontend *fe,
541         int is_punctured)
542 {
543         struct cx8802_dev *dev = fe->dvb->priv;
544         dev->ts_gen_cntrl = 0x2;
545
546         return 0;
547 }
548
549 static int cx24116_reset_device(struct dvb_frontend *fe)
550 {
551         struct cx8802_dev *dev = fe->dvb->priv;
552         struct cx88_core *core = dev->core;
553
554         /* Reset the part */
555         /* Put the cx24116 into reset */
556         cx_write(MO_SRST_IO, 0);
557         msleep(10);
558         /* Take the cx24116 out of reset */
559         cx_write(MO_SRST_IO, 1);
560         msleep(10);
561
562         return 0;
563 }
564
565 static struct cx24116_config hauppauge_hvr4000_config = {
566         .demod_address          = 0x05,
567         .set_ts_params          = cx24116_set_ts_param,
568         .reset_device           = cx24116_reset_device,
569 };
570
571 static struct cx24116_config tevii_s460_config = {
572         .demod_address = 0x55,
573         .set_ts_params = cx24116_set_ts_param,
574         .reset_device  = cx24116_reset_device,
575 };
576
577 static struct stv0299_config tevii_tuner_sharp_config = {
578         .demod_address = 0x68,
579         .inittab = sharp_z0194a__inittab,
580         .mclk = 88000000UL,
581         .invert = 1,
582         .skip_reinit = 0,
583         .lock_output = 1,
584         .volt13_op0_op1 = STV0299_VOLT13_OP1,
585         .min_delay_ms = 100,
586         .set_symbol_rate = sharp_z0194a__set_symbol_rate,
587         .set_ts_params = cx24116_set_ts_param,
588 };
589
590 static struct stv0288_config tevii_tuner_earda_config = {
591         .demod_address = 0x68,
592         .min_delay_ms = 100,
593         .set_ts_params = cx24116_set_ts_param,
594 };
595
596 static int dvb_register(struct cx8802_dev *dev)
597 {
598         //struct cx88_core *core = dev->core;
599
600         ///* init struct videobuf_dvb */
601         //fe->dvb.name = core->name;
602         //dev->ts_gen_cntrl = 0x0c;
603
604         struct cx88_core *core = dev->core;
605         struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
606
607         /* Get the first frontend */
608         fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
609         if (!fe0)
610                 return -EINVAL;
611
612         /* init frontend */
613         switch (core->boardnr) {
614         case CX88_BOARD_HAUPPAUGE_DVB_T1:
615                 fe0->dvb.frontend = dvb_attach(cx22702_attach,
616                                                &connexant_refboard_config,
617                                                &core->i2c_adap);
618                 if (fe0->dvb.frontend != NULL) {
619                         if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
620                                         0x61, &core->i2c_adap,
621                                         DVB_PLL_THOMSON_DTT759X))
622                                 goto frontend_detach;
623                 }
624                 break;
625         case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
626         case CX88_BOARD_CONEXANT_DVB_T1:
627         case CX88_BOARD_KWORLD_DVB_T_CX22702:
628         case CX88_BOARD_WINFAST_DTV1000:
629                 fe0->dvb.frontend = dvb_attach(cx22702_attach,
630                                                &connexant_refboard_config,
631                                                &core->i2c_adap);
632                 if (fe0->dvb.frontend != NULL) {
633                         if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
634                                         0x60, &core->i2c_adap,
635                                         DVB_PLL_THOMSON_DTT7579))
636                                 goto frontend_detach;
637                 }
638                 break;
639         case CX88_BOARD_WINFAST_DTV2000H:
640         case CX88_BOARD_HAUPPAUGE_HVR1100:
641         case CX88_BOARD_HAUPPAUGE_HVR1100LP:
642         case CX88_BOARD_HAUPPAUGE_HVR1300:
643                 fe0->dvb.frontend = dvb_attach(cx22702_attach,
644                                                &hauppauge_hvr_config,
645                                                &core->i2c_adap);
646                 if (fe0->dvb.frontend != NULL) {
647                         if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
648                                    &core->i2c_adap, 0x61,
649                                    TUNER_PHILIPS_FMD1216ME_MK3))
650                                 goto frontend_detach;
651                 }
652                 break;
653         case CX88_BOARD_HAUPPAUGE_HVR3000:
654                 /* DVB-S init */
655                 fe0->dvb.frontend = dvb_attach(cx24123_attach,
656                                &hauppauge_novas_config,
657                                &dev->core->i2c_adap);
658                 if (fe0->dvb.frontend) {
659                         if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
660                         &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
661                                 dprintk( 1, "%s(): HVR3000 - DVB-S LNB Init: failed\n", __FUNCTION__);
662                         }
663                 } else {
664                         dprintk( 1, "%s(): HVR3000 - DVB-S Init: failed\n", __FUNCTION__);
665                 }
666                 /* DVB-T init */
667                 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
668                 if (fe1) {
669                         fe1->dvb.frontend = dvb_attach(cx22702_attach,
670                                 &hauppauge_hvr_config,
671                                 &dev->core->i2c_adap);
672                         if (fe1->dvb.frontend) {
673                                 fe1->dvb.frontend->id = 1;
674                                 if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
675                                                 &dev->core->i2c_adap, 0x61,
676                                                 TUNER_PHILIPS_FMD1216ME_MK3)) {
677                                         dprintk( 1, "%s(): HVR3000 - DVB-T misc Init: failed\n", __FUNCTION__);
678                                 }
679                         } else {
680                                 dprintk( 1, "%s(): HVR3000 - DVB-T Init: failed\n", __FUNCTION__);
681                         }
682                 } else {
683                         dprintk( 1, "%s(): HVR3000 - DVB-T Init: can't find frontend 2.\n", __FUNCTION__);
684                 }
685                 break;
686         case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
687                 fe0->dvb.frontend = dvb_attach(mt352_attach,
688                                                &dvico_fusionhdtv,
689                                                &core->i2c_adap);
690                 if (fe0->dvb.frontend != NULL) {
691                         if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
692                                         0x60, NULL, DVB_PLL_THOMSON_DTT7579))
693                                 goto frontend_detach;
694                         break;
695                 }
696                 /* ZL10353 replaces MT352 on later cards */
697                 fe0->dvb.frontend = dvb_attach(zl10353_attach,
698                                                &dvico_fusionhdtv_plus_v1_1,
699                                                &core->i2c_adap);
700                 if (fe0->dvb.frontend != NULL) {
701                         if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
702                                         0x60, NULL, DVB_PLL_THOMSON_DTT7579))
703                                 goto frontend_detach;
704                 }
705                 break;
706         case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
707                 /* The tin box says DEE1601, but it seems to be DTT7579
708                  * compatible, with a slightly different MT352 AGC gain. */
709                 fe0->dvb.frontend = dvb_attach(mt352_attach,
710                                                &dvico_fusionhdtv_dual,
711                                                &core->i2c_adap);
712                 if (fe0->dvb.frontend != NULL) {
713                         if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
714                                         0x61, NULL, DVB_PLL_THOMSON_DTT7579))
715                                 goto frontend_detach;
716                         break;
717                 }
718                 /* ZL10353 replaces MT352 on later cards */
719                 fe0->dvb.frontend = dvb_attach(zl10353_attach,
720                                                &dvico_fusionhdtv_plus_v1_1,
721                                                &core->i2c_adap);
722                 if (fe0->dvb.frontend != NULL) {
723                         if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
724                                         0x61, NULL, DVB_PLL_THOMSON_DTT7579))
725                                 goto frontend_detach;
726                 }
727                 break;
728         case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
729                 fe0->dvb.frontend = dvb_attach(mt352_attach,
730                                                &dvico_fusionhdtv,
731                                                &core->i2c_adap);
732                 if (fe0->dvb.frontend != NULL) {
733                         if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
734                                         0x61, NULL, DVB_PLL_LG_Z201))
735                                 goto frontend_detach;
736                 }
737                 break;
738         case CX88_BOARD_KWORLD_DVB_T:
739         case CX88_BOARD_DNTV_LIVE_DVB_T:
740         case CX88_BOARD_ADSTECH_DVB_T_PCI:
741                 fe0->dvb.frontend = dvb_attach(mt352_attach,
742                                                &dntv_live_dvbt_config,
743                                                &core->i2c_adap);
744                 if (fe0->dvb.frontend != NULL) {
745                         if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
746                                         0x61, NULL, DVB_PLL_UNKNOWN_1))
747                                 goto frontend_detach;
748                 }
749                 break;
750         case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
751 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
752                 /* MT352 is on a secondary I2C bus made from some GPIO lines */
753                 fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
754                                                &dev->vp3054->adap);
755                 if (fe0->dvb.frontend != NULL) {
756                         if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
757                                         &core->i2c_adap, 0x61,
758                                         TUNER_PHILIPS_FMD1216ME_MK3))
759                                 goto frontend_detach;
760                 }
761 #else
762                 printk(KERN_ERR "%s/2: built without vp3054 support\n",
763                                 core->name);
764 #endif
765                 break;
766         case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
767                 fe0->dvb.frontend = dvb_attach(zl10353_attach,
768                                                &dvico_fusionhdtv_hybrid,
769                                                &core->i2c_adap);
770                 if (fe0->dvb.frontend != NULL) {
771                         if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
772                                    &core->i2c_adap, 0x61,
773                                    TUNER_THOMSON_FE6600))
774                                 goto frontend_detach;
775                 }
776                 break;
777         case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
778                 fe0->dvb.frontend = dvb_attach(zl10353_attach,
779                                                &dvico_fusionhdtv_xc3028,
780                                                &core->i2c_adap);
781                 if (fe0->dvb.frontend == NULL)
782                         fe0->dvb.frontend = dvb_attach(mt352_attach,
783                                                 &dvico_fusionhdtv_mt352_xc3028,
784                                                 &core->i2c_adap);
785                 /*
786                  * On this board, the demod provides the I2C bus pullup.
787                  * We must not permit gate_ctrl to be performed, or
788                  * the xc3028 cannot communicate on the bus.
789                  */
790                 if (fe0->dvb.frontend)
791                         fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
792                 if (attach_xc3028(0x61, dev) < 0)
793                         return -EINVAL;
794                 break;
795         case CX88_BOARD_PCHDTV_HD3000:
796                 fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
797                                                &core->i2c_adap);
798                 if (fe0->dvb.frontend != NULL) {
799                         if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
800                                         &core->i2c_adap, 0x61,
801                                         TUNER_THOMSON_DTT761X))
802                                 goto frontend_detach;
803                 }
804                 break;
805         case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
806                 dev->ts_gen_cntrl = 0x08;
807
808                 /* Do a hardware reset of chip before using it. */
809                 cx_clear(MO_GP0_IO, 1);
810                 mdelay(100);
811                 cx_set(MO_GP0_IO, 1);
812                 mdelay(200);
813
814                 /* Select RF connector callback */
815                 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
816                 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
817                                                &fusionhdtv_3_gold,
818                                                &core->i2c_adap);
819                 if (fe0->dvb.frontend != NULL) {
820                         if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
821                                         &core->i2c_adap, 0x61,
822                                         TUNER_MICROTUNE_4042FI5))
823                                 goto frontend_detach;
824                 }
825                 break;
826         case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
827                 dev->ts_gen_cntrl = 0x08;
828
829                 /* Do a hardware reset of chip before using it. */
830                 cx_clear(MO_GP0_IO, 1);
831                 mdelay(100);
832                 cx_set(MO_GP0_IO, 9);
833                 mdelay(200);
834                 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
835                                                &fusionhdtv_3_gold,
836                                                &core->i2c_adap);
837                 if (fe0->dvb.frontend != NULL) {
838                         if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
839                                         &core->i2c_adap, 0x61,
840                                         TUNER_THOMSON_DTT761X))
841                                 goto frontend_detach;
842                 }
843                 break;
844         case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
845                 dev->ts_gen_cntrl = 0x08;
846
847                 /* Do a hardware reset of chip before using it. */
848                 cx_clear(MO_GP0_IO, 1);
849                 mdelay(100);
850                 cx_set(MO_GP0_IO, 1);
851                 mdelay(200);
852                 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
853                                                &fusionhdtv_5_gold,
854                                                &core->i2c_adap);
855                 if (fe0->dvb.frontend != NULL) {
856                         if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
857                                         &core->i2c_adap, 0x61,
858                                         TUNER_LG_TDVS_H06XF))
859                                 goto frontend_detach;
860                         if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
861                                    &core->i2c_adap, 0x43))
862                                 goto frontend_detach;
863                 }
864                 break;
865         case CX88_BOARD_PCHDTV_HD5500:
866                 dev->ts_gen_cntrl = 0x08;
867
868                 /* Do a hardware reset of chip before using it. */
869                 cx_clear(MO_GP0_IO, 1);
870                 mdelay(100);
871                 cx_set(MO_GP0_IO, 1);
872                 mdelay(200);
873                 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
874                                                &pchdtv_hd5500,
875                                                &core->i2c_adap);
876                 if (fe0->dvb.frontend != NULL) {
877                         if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
878                                         &core->i2c_adap, 0x61,
879                                         TUNER_LG_TDVS_H06XF))
880                                 goto frontend_detach;
881                         if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
882                                    &core->i2c_adap, 0x43))
883                                 goto frontend_detach;
884                 }
885                 break;
886         case CX88_BOARD_ATI_HDTVWONDER:
887                 fe0->dvb.frontend = dvb_attach(nxt200x_attach,
888                                                &ati_hdtvwonder,
889                                                &core->i2c_adap);
890                 if (fe0->dvb.frontend != NULL) {
891                         if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
892                                         &core->i2c_adap, 0x61,
893                                         TUNER_PHILIPS_TUV1236D))
894                                 goto frontend_detach;
895                 }
896                 break;
897         case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
898         case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
899                 fe0->dvb.frontend = dvb_attach(cx24123_attach,
900                                                &hauppauge_novas_config,
901                                                &core->i2c_adap);
902                 if (fe0->dvb.frontend) {
903                         if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
904                                         &core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
905                                 goto frontend_detach;
906                 }
907                 break;
908         case CX88_BOARD_KWORLD_DVBS_100:
909                 fe0->dvb.frontend = dvb_attach(cx24123_attach,
910                                                &kworld_dvbs_100_config,
911                                                &core->i2c_adap);
912                 if (fe0->dvb.frontend) {
913                         core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
914                         fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
915                 }
916                 break;
917         case CX88_BOARD_GENIATECH_DVBS:
918                 fe0->dvb.frontend = dvb_attach(cx24123_attach,
919                                                &geniatech_dvbs_config,
920                                                &core->i2c_adap);
921                 if (fe0->dvb.frontend) {
922                         core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
923                         fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
924                 }
925                 break;
926         case CX88_BOARD_PINNACLE_PCTV_HD_800i:
927                 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
928                                                &pinnacle_pctv_hd_800i_config,
929                                                &core->i2c_adap);
930                 if (fe0->dvb.frontend != NULL) {
931                         if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
932                                         &core->i2c_adap,
933                                         &pinnacle_pctv_hd_800i_tuner_config))
934                                 goto frontend_detach;
935                 }
936                 break;
937         case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
938                 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
939                                                 &dvico_hdtv5_pci_nano_config,
940                                                 &core->i2c_adap);
941                 if (fe0->dvb.frontend != NULL) {
942                         struct dvb_frontend *fe;
943                         struct xc2028_config cfg = {
944                                 .i2c_adap  = &core->i2c_adap,
945                                 .i2c_addr  = 0x61,
946                         };
947                         static struct xc2028_ctrl ctl = {
948                                 .fname       = XC2028_DEFAULT_FIRMWARE,
949                                 .max_len     = 64,
950                                 .scode_table = XC3028_FE_OREN538,
951                         };
952
953                         fe = dvb_attach(xc2028_attach,
954                                         fe0->dvb.frontend, &cfg);
955                         if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
956                                 fe->ops.tuner_ops.set_config(fe, &ctl);
957                 }
958                 break;
959          case CX88_BOARD_PINNACLE_HYBRID_PCTV:
960                 fe0->dvb.frontend = dvb_attach(zl10353_attach,
961                                                &cx88_pinnacle_hybrid_pctv,
962                                                &core->i2c_adap);
963                 if (fe0->dvb.frontend) {
964                         fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
965                         if (attach_xc3028(0x61, dev) < 0)
966                                 goto frontend_detach;
967                 }
968                 break;
969          case CX88_BOARD_GENIATECH_X8000_MT:
970                 dev->ts_gen_cntrl = 0x00;
971
972                 fe0->dvb.frontend = dvb_attach(zl10353_attach,
973                                                &cx88_geniatech_x8000_mt,
974                                                &core->i2c_adap);
975                 if (attach_xc3028(0x61, dev) < 0)
976                         goto frontend_detach;
977                 break;
978          case CX88_BOARD_KWORLD_ATSC_120:
979                 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
980                                                &kworld_atsc_120_config,
981                                                &core->i2c_adap);
982                 if (attach_xc3028(0x61, dev) < 0)
983                         goto frontend_detach;
984                 break;
985         case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
986                 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
987                                                &dvico_fusionhdtv7_config,
988                                                &core->i2c_adap);
989                 if (fe0->dvb.frontend != NULL) {
990                         if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
991                                         &core->i2c_adap,
992                                         &dvico_fusionhdtv7_tuner_config))
993                                 goto frontend_detach;
994                 }
995                 break;
996         case CX88_BOARD_HAUPPAUGE_HVR4000:
997                 /* DVB-S/S2 Init */
998                 fe0->dvb.frontend = dvb_attach(cx24116_attach,
999                         &hauppauge_hvr4000_config,
1000                         &dev->core->i2c_adap);
1001                 if (fe0->dvb.frontend) {
1002                         if(!dvb_attach(isl6421_attach, fe0->dvb.frontend,
1003                                 &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
1004                                 dprintk( 1, "%s(): HVR4000 - DVB-S LNB Init: failed\n", __FUNCTION__);
1005                         }
1006                 } else {
1007                         dprintk( 1, "%s(): HVR4000 - DVB-S Init: failed\n", __FUNCTION__);
1008                 }
1009                 /* DVB-T Init */
1010                 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1011                 if (fe1) {
1012                         fe1->dvb.frontend = dvb_attach(cx22702_attach,
1013                                 &hauppauge_hvr_config,
1014                                 &dev->core->i2c_adap);
1015                         if (fe1->dvb.frontend) {
1016                                 fe1->dvb.frontend->id = 1;
1017                                 if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
1018                                         &dev->core->i2c_adap, 0x61,
1019                                         TUNER_PHILIPS_FMD1216ME_MK3)) {
1020                                         dprintk( 1, "%s(): HVR4000 - DVB-T misc Init: failed\n", __FUNCTION__);
1021                                 }
1022                         } else {
1023                                 dprintk( 1, "%s(): HVR4000 - DVB-T Init: failed\n", __FUNCTION__);
1024                         }
1025                 } else {
1026                         dprintk( 1, "%s(): HVR4000 - DVB-T Init: can't find frontend 2.\n", __FUNCTION__);
1027                 }
1028                 break;
1029         case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
1030                 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1031                         &hauppauge_hvr4000_config,
1032                         &dev->core->i2c_adap);
1033                 if (fe0->dvb.frontend) {
1034                         dvb_attach(isl6421_attach, fe0->dvb.frontend,
1035                                 &dev->core->i2c_adap,
1036                                 0x08, ISL6421_DCL, 0x00);
1037                 }
1038                 break;
1039         case CX88_BOARD_TEVII_S420:
1040                 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1041                                                 &tevii_tuner_sharp_config,
1042                                                 &core->i2c_adap);
1043                 if (fe0->dvb.frontend != NULL) {
1044                         if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
1045                                         &core->i2c_adap, DVB_PLL_OPERA1))
1046                                 goto frontend_detach;
1047                         core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1048                         fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1049
1050                 } else {
1051                         fe0->dvb.frontend = dvb_attach(stv0288_attach,
1052                                                             &tevii_tuner_earda_config,
1053                                                             &core->i2c_adap);
1054                                 if (fe0->dvb.frontend != NULL) {
1055                                         if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
1056                                                 &core->i2c_adap))
1057                                         goto frontend_detach;
1058                                 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1059                                 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1060
1061                         }
1062                 }
1063                 break;
1064         case CX88_BOARD_TEVII_S460:
1065                 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1066                                                &tevii_s460_config,
1067                                                &core->i2c_adap);
1068                 if (fe0->dvb.frontend != NULL) {
1069                         core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1070                         fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1071                 }
1072                 break;
1073         case CX88_BOARD_OMICOM_SS4_PCI:
1074         case CX88_BOARD_TBS_8920:
1075         case CX88_BOARD_PROF_7300:
1076                 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1077                                                &hauppauge_hvr4000_config,
1078                                                &core->i2c_adap);
1079                 if (fe0->dvb.frontend != NULL) {
1080                         core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1081                         fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1082                 }
1083                 break;
1084         default:
1085                 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1086                        core->name);
1087                 break;
1088         }
1089
1090         if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
1091                 printk(KERN_ERR
1092                        "%s/2: frontend initialization failed\n",
1093                        core->name);
1094                 return -EINVAL;
1095         }
1096         /* define general-purpose callback pointer */
1097         fe0->dvb.frontend->callback = cx88_tuner_callback;
1098
1099         /* Ensure all frontends negotiate bus access */
1100         fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1101         if (fe1)
1102                 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1103
1104         /* Put the analog decoder in standby to keep it quiet */
1105         cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
1106
1107         /* register everything */
1108         return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1109                 &dev->pci->dev, adapter_nr);
1110
1111 frontend_detach:
1112         if (fe0->dvb.frontend) {
1113                 dvb_frontend_detach(fe0->dvb.frontend);
1114                 fe0->dvb.frontend = NULL;
1115         }
1116         return -EINVAL;
1117 }
1118
1119 /* ----------------------------------------------------------- */
1120
1121 /* CX8802 MPEG -> mini driver - We have been given the hardware */
1122 static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
1123 {
1124         struct cx88_core *core = drv->core;
1125         int err = 0;
1126         dprintk( 1, "%s\n", __func__);
1127
1128         switch (core->boardnr) {
1129         case CX88_BOARD_HAUPPAUGE_HVR1300:
1130                 /* We arrive here with either the cx23416 or the cx22702
1131                  * on the bus. Take the bus from the cx23416 and enable the
1132                  * cx22702 demod
1133                  */
1134                 cx_set(MO_GP0_IO,   0x00000080); /* cx22702 out of reset and enable */
1135                 cx_clear(MO_GP0_IO, 0x00000004);
1136                 udelay(1000);
1137                 break;
1138
1139         case CX88_BOARD_HAUPPAUGE_HVR3000: /* ? */
1140                 if(core->dvbdev->frontends.active_fe_id == 1) {
1141                         /* DVB-S/S2 Enabled */
1142
1143                         /* Toggle reset on cx22702 leaving i2c active */
1144                         cx_write(MO_GP0_IO, core->board.input[0].gpio0);
1145                         udelay(1000);
1146                         cx_clear(MO_GP0_IO, 0x00000080);
1147                         udelay(50);
1148                         cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */
1149                         cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */
1150                         udelay(1000);
1151
1152                         cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */
1153                         core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1154                 } else
1155                 if (core->dvbdev->frontends.active_fe_id == 2) {
1156                         /* DVB-T Enabled */
1157
1158                         /* Put the cx24116/cx24123 into reset */
1159                         cx_write(MO_SRST_IO, 0);
1160
1161                         /* cx22702 out of reset and enable it */
1162                         cx_set(MO_GP0_IO,   0x00000080);
1163                         cx_clear(MO_GP0_IO, 0x00000004);
1164                         core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1165                         udelay(1000);
1166                 }
1167                 break;
1168         case CX88_BOARD_HAUPPAUGE_HVR4000:
1169                 if(core->dvbdev->frontends.active_fe_id == 1) {
1170                         /* DVB-S/S2 Enabled */
1171
1172                         /* Toggle reset on cx22702 leaving i2c active */
1173                         cx_write(MO_GP0_IO, (core->board.input[0].gpio0 & 0x0000ff00) | 0x00000080);
1174                         udelay(1000);
1175                         cx_clear(MO_GP0_IO, 0x00000080);
1176                         udelay(50);
1177                         cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */
1178                         cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */
1179                         udelay(1000);
1180
1181                         cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */
1182                         core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1183                 } else
1184                 if (core->dvbdev->frontends.active_fe_id == 2) {
1185                         /* DVB-T Enabled */
1186
1187                         /* Put the cx24116/cx24123 into reset */
1188                         cx_write(MO_SRST_IO, 0);
1189
1190                         /* cx22702 out of reset and enable it */
1191                         cx_set(MO_GP0_IO,   0x00000080);
1192                         cx_clear(MO_GP0_IO, 0x00000004);
1193                         core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1194                         udelay(1000);
1195                 }
1196                 break;
1197
1198         default:
1199                 err = -ENODEV;
1200         }
1201         return err;
1202 }
1203
1204 /* CX8802 MPEG -> mini driver - We no longer have the hardware */
1205 static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
1206 {
1207         struct cx88_core *core = drv->core;
1208         int err = 0;
1209         dprintk( 1, "%s\n", __func__);
1210
1211         switch (core->boardnr) {
1212         case CX88_BOARD_HAUPPAUGE_HVR1300:
1213                 /* Do Nothing, leave the cx22702 on the bus. */
1214                 break;
1215         case CX88_BOARD_HAUPPAUGE_HVR3000:
1216         case CX88_BOARD_HAUPPAUGE_HVR4000:
1217                 break;
1218         default:
1219                 err = -ENODEV;
1220         }
1221         return err;
1222 }
1223
1224 static int cx8802_dvb_probe(struct cx8802_driver *drv)
1225 {
1226         struct cx88_core *core = drv->core;
1227         struct cx8802_dev *dev = drv->core->dvbdev;
1228         int err,i;
1229         struct videobuf_dvb_frontend *fe;
1230
1231         dprintk( 1, "%s\n", __func__);
1232         dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1233                 core->boardnr,
1234                 core->name,
1235                 core->pci_bus,
1236                 core->pci_slot);
1237
1238         err = -ENODEV;
1239         if (!(core->board.mpeg & CX88_MPEG_DVB))
1240                 goto fail_core;
1241
1242         /* If vp3054 isn't enabled, a stub will just return 0 */
1243         err = vp3054_i2c_probe(dev);
1244         if (0 != err)
1245                 goto fail_core;
1246
1247         /* dvb stuff */
1248         printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1249         dev->ts_gen_cntrl = 0x0c;
1250
1251         for (i = 1; i <= core->board.num_frontends; i++) {
1252                 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
1253                 if (!fe) {
1254                         printk(KERN_ERR "%s() failed to get frontend(%d)\n", __FUNCTION__, i);
1255                         continue;
1256                 }
1257                 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
1258                             &dev->pci->dev, &dev->slock,
1259                             V4L2_BUF_TYPE_VIDEO_CAPTURE,
1260                             V4L2_FIELD_TOP,
1261                             sizeof(struct cx88_buffer),
1262                             dev);
1263                 /* init struct videobuf_dvb */
1264                 fe->dvb.name = dev->core->name;
1265         }
1266         err = dvb_register(dev);
1267         if (err != 0)
1268                 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
1269                        core->name, err);
1270
1271  fail_core:
1272         return err;
1273 }
1274
1275 static int cx8802_dvb_remove(struct cx8802_driver *drv)
1276 {
1277         struct cx8802_dev *dev = drv->core->dvbdev;
1278
1279         videobuf_dvb_unregister_bus(&dev->frontends);
1280
1281         vp3054_i2c_remove(dev);
1282
1283         return 0;
1284 }
1285
1286 static struct cx8802_driver cx8802_dvb_driver = {
1287         .type_id        = CX88_MPEG_DVB,
1288         .hw_access      = CX8802_DRVCTL_SHARED,
1289         .probe          = cx8802_dvb_probe,
1290         .remove         = cx8802_dvb_remove,
1291         .advise_acquire = cx8802_dvb_advise_acquire,
1292         .advise_release = cx8802_dvb_advise_release,
1293 };
1294
1295 static int dvb_init(void)
1296 {
1297         printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n",
1298                (CX88_VERSION_CODE >> 16) & 0xff,
1299                (CX88_VERSION_CODE >>  8) & 0xff,
1300                CX88_VERSION_CODE & 0xff);
1301 #ifdef SNAPSHOT
1302         printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
1303                SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1304 #endif
1305         return cx8802_register_driver(&cx8802_dvb_driver);
1306 }
1307
1308 static void dvb_fini(void)
1309 {
1310         cx8802_unregister_driver(&cx8802_dvb_driver);
1311 }
1312
1313 module_init(dvb_init);
1314 module_exit(dvb_fini);
1315
1316 /*
1317  * Local variables:
1318  * c-basic-offset: 8
1319  * compile-command: "make DVB=1"
1320  * End:
1321  */