Merge branch 'imx-for-2.6.38' of git://git.pengutronix.de/git/ukl/linux-2.6 into...
[pandora-kernel.git] / drivers / media / video / cx231xx / cx231xx-dvb.c
1 /*
2  DVB device driver for cx231xx
3
4  Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
5                 Based on em28xx driver
6
7  This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include <linux/kernel.h>
23 #include <linux/slab.h>
24 #include <linux/usb.h>
25
26 #include "cx231xx.h"
27 #include <media/v4l2-common.h>
28 #include <media/videobuf-vmalloc.h>
29
30 #include "xc5000.h"
31 #include "dvb_dummy_fe.h"
32 #include "s5h1432.h"
33 #include "tda18271.h"
34 #include "s5h1411.h"
35 #include "lgdt3305.h"
36
37 MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
38 MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
39 MODULE_LICENSE("GPL");
40
41 static unsigned int debug;
42 module_param(debug, int, 0644);
43 MODULE_PARM_DESC(debug, "enable debug messages [dvb]");
44
45 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
46
47 #define dprintk(level, fmt, arg...) do {                        \
48 if (debug >= level)                                             \
49         printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \
50 } while (0)
51
52 #define CX231XX_DVB_NUM_BUFS 5
53 #define CX231XX_DVB_MAX_PACKETSIZE 564
54 #define CX231XX_DVB_MAX_PACKETS 64
55
56 struct cx231xx_dvb {
57         struct dvb_frontend *frontend;
58
59         /* feed count management */
60         struct mutex lock;
61         int nfeeds;
62
63         /* general boilerplate stuff */
64         struct dvb_adapter adapter;
65         struct dvb_demux demux;
66         struct dmxdev dmxdev;
67         struct dmx_frontend fe_hw;
68         struct dmx_frontend fe_mem;
69         struct dvb_net net;
70 };
71
72 static struct s5h1432_config dvico_s5h1432_config = {
73         .output_mode   = S5H1432_SERIAL_OUTPUT,
74         .gpio          = S5H1432_GPIO_ON,
75         .qam_if        = S5H1432_IF_4000,
76         .vsb_if        = S5H1432_IF_4000,
77         .inversion     = S5H1432_INVERSION_OFF,
78         .status_mode   = S5H1432_DEMODLOCKING,
79         .mpeg_timing   = S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
80 };
81
82 static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = {
83         .dvbt_6   = { .if_freq = 4000, .agc_mode = 3, .std = 4,
84                       .if_lvl = 1, .rfagc_top = 0x37, },
85         .dvbt_7   = { .if_freq = 4000, .agc_mode = 3, .std = 5,
86                       .if_lvl = 1, .rfagc_top = 0x37, },
87         .dvbt_8   = { .if_freq = 4000, .agc_mode = 3, .std = 6,
88                       .if_lvl = 1, .rfagc_top = 0x37, },
89 };
90
91 static struct tda18271_config cnxt_rde253s_tunerconfig = {
92         .std_map = &cnxt_rde253s_tda18271_std_map,
93         .gate    = TDA18271_GATE_ANALOG,
94 };
95
96 static struct s5h1411_config tda18271_s5h1411_config = {
97         .output_mode   = S5H1411_SERIAL_OUTPUT,
98         .gpio          = S5H1411_GPIO_OFF,
99         .vsb_if        = S5H1411_IF_3250,
100         .qam_if        = S5H1411_IF_4000,
101         .inversion     = S5H1411_INVERSION_ON,
102         .status_mode   = S5H1411_DEMODLOCKING,
103         .mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
104 };
105 static struct s5h1411_config xc5000_s5h1411_config = {
106         .output_mode   = S5H1411_SERIAL_OUTPUT,
107         .gpio          = S5H1411_GPIO_OFF,
108         .vsb_if        = S5H1411_IF_3250,
109         .qam_if        = S5H1411_IF_3250,
110         .inversion     = S5H1411_INVERSION_OFF,
111         .status_mode   = S5H1411_DEMODLOCKING,
112         .mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
113 };
114
115 static struct lgdt3305_config hcw_lgdt3305_config = {
116         .i2c_addr           = 0x0e,
117         .mpeg_mode          = LGDT3305_MPEG_SERIAL,
118         .tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
119         .tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
120         .deny_i2c_rptr      = 1,
121         .spectral_inversion = 1,
122         .qam_if_khz         = 4000,
123         .vsb_if_khz         = 3250,
124 };
125
126 static struct tda18271_std_map hauppauge_tda18271_std_map = {
127         .atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 4,
128                       .if_lvl = 1, .rfagc_top = 0x58, },
129         .qam_6    = { .if_freq = 4000, .agc_mode = 3, .std = 5,
130                       .if_lvl = 1, .rfagc_top = 0x58, },
131 };
132
133 static struct tda18271_config hcw_tda18271_config = {
134         .std_map = &hauppauge_tda18271_std_map,
135         .gate    = TDA18271_GATE_DIGITAL,
136 };
137
138 static inline void print_err_status(struct cx231xx *dev, int packet, int status)
139 {
140         char *errmsg = "Unknown";
141
142         switch (status) {
143         case -ENOENT:
144                 errmsg = "unlinked synchronuously";
145                 break;
146         case -ECONNRESET:
147                 errmsg = "unlinked asynchronuously";
148                 break;
149         case -ENOSR:
150                 errmsg = "Buffer error (overrun)";
151                 break;
152         case -EPIPE:
153                 errmsg = "Stalled (device not responding)";
154                 break;
155         case -EOVERFLOW:
156                 errmsg = "Babble (bad cable?)";
157                 break;
158         case -EPROTO:
159                 errmsg = "Bit-stuff error (bad cable?)";
160                 break;
161         case -EILSEQ:
162                 errmsg = "CRC/Timeout (could be anything)";
163                 break;
164         case -ETIME:
165                 errmsg = "Device does not respond";
166                 break;
167         }
168         if (packet < 0) {
169                 dprintk(1, "URB status %d [%s].\n", status, errmsg);
170         } else {
171                 dprintk(1, "URB packet %d, status %d [%s].\n",
172                         packet, status, errmsg);
173         }
174 }
175
176 static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb)
177 {
178         int i;
179
180         if (!dev)
181                 return 0;
182
183         if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
184                 return 0;
185
186         if (urb->status < 0) {
187                 print_err_status(dev, -1, urb->status);
188                 if (urb->status == -ENOENT)
189                         return 0;
190         }
191
192         for (i = 0; i < urb->number_of_packets; i++) {
193                 int status = urb->iso_frame_desc[i].status;
194
195                 if (status < 0) {
196                         print_err_status(dev, i, status);
197                         if (urb->iso_frame_desc[i].status != -EPROTO)
198                                 continue;
199                 }
200
201                 dvb_dmx_swfilter(&dev->dvb->demux,
202                                  urb->transfer_buffer +
203                                 urb->iso_frame_desc[i].offset,
204                                 urb->iso_frame_desc[i].actual_length);
205         }
206
207         return 0;
208 }
209
210 static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb)
211 {
212         if (!dev)
213                 return 0;
214
215         if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
216                 return 0;
217
218         if (urb->status < 0) {
219                 print_err_status(dev, -1, urb->status);
220                 if (urb->status == -ENOENT)
221                         return 0;
222         }
223
224         /* Feed the transport payload into the kernel demux */
225         dvb_dmx_swfilter(&dev->dvb->demux,
226                 urb->transfer_buffer, urb->actual_length);
227
228         return 0;
229 }
230
231 static int start_streaming(struct cx231xx_dvb *dvb)
232 {
233         int rc;
234         struct cx231xx *dev = dvb->adapter.priv;
235
236         if (dev->USE_ISO) {
237                 cx231xx_info("DVB transfer mode is ISO.\n");
238                 mutex_lock(&dev->i2c_lock);
239                 cx231xx_enable_i2c_port_3(dev, false);
240                 cx231xx_set_alt_setting(dev, INDEX_TS1, 4);
241                 cx231xx_enable_i2c_port_3(dev, true);
242                 mutex_unlock(&dev->i2c_lock);
243                 rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
244                 if (rc < 0)
245                         return rc;
246                 dev->mode_tv = 1;
247                 return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS,
248                                         CX231XX_DVB_NUM_BUFS,
249                                         dev->ts1_mode.max_pkt_size,
250                                         dvb_isoc_copy);
251         } else {
252                 cx231xx_info("DVB transfer mode is BULK.\n");
253                 cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
254                 rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
255                 if (rc < 0)
256                         return rc;
257                 dev->mode_tv = 1;
258                 return cx231xx_init_bulk(dev, CX231XX_DVB_MAX_PACKETS,
259                                         CX231XX_DVB_NUM_BUFS,
260                                         dev->ts1_mode.max_pkt_size,
261                                         dvb_bulk_copy);
262         }
263
264 }
265
266 static int stop_streaming(struct cx231xx_dvb *dvb)
267 {
268         struct cx231xx *dev = dvb->adapter.priv;
269
270         if (dev->USE_ISO)
271                 cx231xx_uninit_isoc(dev);
272         else
273                 cx231xx_uninit_bulk(dev);
274
275         cx231xx_set_mode(dev, CX231XX_SUSPEND);
276
277         return 0;
278 }
279
280 static int start_feed(struct dvb_demux_feed *feed)
281 {
282         struct dvb_demux *demux = feed->demux;
283         struct cx231xx_dvb *dvb = demux->priv;
284         int rc, ret;
285
286         if (!demux->dmx.frontend)
287                 return -EINVAL;
288
289         mutex_lock(&dvb->lock);
290         dvb->nfeeds++;
291         rc = dvb->nfeeds;
292
293         if (dvb->nfeeds == 1) {
294                 ret = start_streaming(dvb);
295                 if (ret < 0)
296                         rc = ret;
297         }
298
299         mutex_unlock(&dvb->lock);
300         return rc;
301 }
302
303 static int stop_feed(struct dvb_demux_feed *feed)
304 {
305         struct dvb_demux *demux = feed->demux;
306         struct cx231xx_dvb *dvb = demux->priv;
307         int err = 0;
308
309         mutex_lock(&dvb->lock);
310         dvb->nfeeds--;
311
312         if (0 == dvb->nfeeds)
313                 err = stop_streaming(dvb);
314
315         mutex_unlock(&dvb->lock);
316         return err;
317 }
318
319 /* ------------------------------------------------------------------ */
320 static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
321 {
322         struct cx231xx *dev = fe->dvb->priv;
323
324         if (acquire)
325                 return cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
326         else
327                 return cx231xx_set_mode(dev, CX231XX_SUSPEND);
328 }
329
330 /* ------------------------------------------------------------------ */
331
332 static struct xc5000_config cnxt_rde250_tunerconfig = {
333         .i2c_address = 0x61,
334         .if_khz = 4000,
335 };
336 static struct xc5000_config cnxt_rdu250_tunerconfig = {
337         .i2c_address = 0x61,
338         .if_khz = 3250,
339 };
340
341 /* ------------------------------------------------------------------ */
342 #if 0
343 static int attach_xc5000(u8 addr, struct cx231xx *dev)
344 {
345
346         struct dvb_frontend *fe;
347         struct xc5000_config cfg;
348
349         memset(&cfg, 0, sizeof(cfg));
350         cfg.i2c_adap = &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap;
351         cfg.i2c_addr = addr;
352
353         if (!dev->dvb->frontend) {
354                 printk(KERN_ERR "%s/2: dvb frontend not attached. "
355                        "Can't attach xc5000\n", dev->name);
356                 return -EINVAL;
357         }
358
359         fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg);
360         if (!fe) {
361                 printk(KERN_ERR "%s/2: xc5000 attach failed\n", dev->name);
362                 dvb_frontend_detach(dev->dvb->frontend);
363                 dev->dvb->frontend = NULL;
364                 return -EINVAL;
365         }
366
367         printk(KERN_INFO "%s/2: xc5000 attached\n", dev->name);
368
369         return 0;
370 }
371 #endif
372
373 int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq)
374 {
375         int status = 0;
376
377         if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
378
379                 struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
380
381                 if (dops->set_analog_params != NULL) {
382                         struct analog_parameters params;
383
384                         params.frequency = freq;
385                         params.std = dev->norm;
386                         params.mode = 0;        /* 0- Air; 1 - cable */
387                         /*params.audmode = ;       */
388
389                         /* Set the analog parameters to set the frequency */
390                         dops->set_analog_params(dev->dvb->frontend, &params);
391                 }
392
393         }
394
395         return status;
396 }
397
398 int cx231xx_reset_analog_tuner(struct cx231xx *dev)
399 {
400         int status = 0;
401
402         if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
403
404                 struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
405
406                 if (dops->init != NULL && !dev->xc_fw_load_done) {
407
408                         cx231xx_info("Reloading firmware for XC5000\n");
409                         status = dops->init(dev->dvb->frontend);
410                         if (status == 0) {
411                                 dev->xc_fw_load_done = 1;
412                                 cx231xx_info
413                                     ("XC5000 firmware download completed\n");
414                         } else {
415                                 dev->xc_fw_load_done = 0;
416                                 cx231xx_info
417                                     ("XC5000 firmware download failed !!!\n");
418                         }
419                 }
420
421         }
422
423         return status;
424 }
425
426 /* ------------------------------------------------------------------ */
427
428 static int register_dvb(struct cx231xx_dvb *dvb,
429                         struct module *module,
430                         struct cx231xx *dev, struct device *device)
431 {
432         int result;
433
434         mutex_init(&dvb->lock);
435
436         /* register adapter */
437         result = dvb_register_adapter(&dvb->adapter, dev->name, module, device,
438                                       adapter_nr);
439         if (result < 0) {
440                 printk(KERN_WARNING
441                        "%s: dvb_register_adapter failed (errno = %d)\n",
442                        dev->name, result);
443                 goto fail_adapter;
444         }
445
446         /* Ensure all frontends negotiate bus access */
447         dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl;
448
449         dvb->adapter.priv = dev;
450
451         /* register frontend */
452         result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
453         if (result < 0) {
454                 printk(KERN_WARNING
455                        "%s: dvb_register_frontend failed (errno = %d)\n",
456                        dev->name, result);
457                 goto fail_frontend;
458         }
459
460         /* register demux stuff */
461         dvb->demux.dmx.capabilities =
462             DMX_TS_FILTERING | DMX_SECTION_FILTERING |
463             DMX_MEMORY_BASED_FILTERING;
464         dvb->demux.priv = dvb;
465         dvb->demux.filternum = 256;
466         dvb->demux.feednum = 256;
467         dvb->demux.start_feed = start_feed;
468         dvb->demux.stop_feed = stop_feed;
469
470         result = dvb_dmx_init(&dvb->demux);
471         if (result < 0) {
472                 printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n",
473                        dev->name, result);
474                 goto fail_dmx;
475         }
476
477         dvb->dmxdev.filternum = 256;
478         dvb->dmxdev.demux = &dvb->demux.dmx;
479         dvb->dmxdev.capabilities = 0;
480         result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
481         if (result < 0) {
482                 printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
483                        dev->name, result);
484                 goto fail_dmxdev;
485         }
486
487         dvb->fe_hw.source = DMX_FRONTEND_0;
488         result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
489         if (result < 0) {
490                 printk(KERN_WARNING
491                        "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
492                        dev->name, result);
493                 goto fail_fe_hw;
494         }
495
496         dvb->fe_mem.source = DMX_MEMORY_FE;
497         result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
498         if (result < 0) {
499                 printk(KERN_WARNING
500                        "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
501                        dev->name, result);
502                 goto fail_fe_mem;
503         }
504
505         result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
506         if (result < 0) {
507                 printk(KERN_WARNING
508                        "%s: connect_frontend failed (errno = %d)\n", dev->name,
509                        result);
510                 goto fail_fe_conn;
511         }
512
513         /* register network adapter */
514         dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
515         return 0;
516
517 fail_fe_conn:
518         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
519 fail_fe_mem:
520         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
521 fail_fe_hw:
522         dvb_dmxdev_release(&dvb->dmxdev);
523 fail_dmxdev:
524         dvb_dmx_release(&dvb->demux);
525 fail_dmx:
526         dvb_unregister_frontend(dvb->frontend);
527 fail_frontend:
528         dvb_frontend_detach(dvb->frontend);
529         dvb_unregister_adapter(&dvb->adapter);
530 fail_adapter:
531         return result;
532 }
533
534 static void unregister_dvb(struct cx231xx_dvb *dvb)
535 {
536         dvb_net_release(&dvb->net);
537         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
538         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
539         dvb_dmxdev_release(&dvb->dmxdev);
540         dvb_dmx_release(&dvb->demux);
541         dvb_unregister_frontend(dvb->frontend);
542         dvb_frontend_detach(dvb->frontend);
543         dvb_unregister_adapter(&dvb->adapter);
544 }
545
546 static int dvb_init(struct cx231xx *dev)
547 {
548         int result = 0;
549         struct cx231xx_dvb *dvb;
550
551         if (!dev->board.has_dvb) {
552                 /* This device does not support the extension */
553                 return 0;
554         }
555
556         dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL);
557
558         if (dvb == NULL) {
559                 printk(KERN_INFO "cx231xx_dvb: memory allocation failed\n");
560                 return -ENOMEM;
561         }
562         dev->dvb = dvb;
563         dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
564         dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;
565
566         mutex_lock(&dev->lock);
567         cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
568         cx231xx_demod_reset(dev);
569         /* init frontend */
570         switch (dev->model) {
571         case CX231XX_BOARD_CNXT_CARRAERA:
572         case CX231XX_BOARD_CNXT_RDE_250:
573
574                 dev->dvb->frontend = dvb_attach(s5h1432_attach,
575                                         &dvico_s5h1432_config,
576                                         &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
577
578                 if (dev->dvb->frontend == NULL) {
579                         printk(DRIVER_NAME
580                                ": Failed to attach s5h1432 front end\n");
581                         result = -EINVAL;
582                         goto out_free;
583                 }
584
585                 /* define general-purpose callback pointer */
586                 dvb->frontend->callback = cx231xx_tuner_callback;
587
588                 if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
589                                &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
590                                &cnxt_rde250_tunerconfig)) {
591                         result = -EINVAL;
592                         goto out_free;
593                 }
594
595                 break;
596         case CX231XX_BOARD_CNXT_SHELBY:
597         case CX231XX_BOARD_CNXT_RDU_250:
598
599                 dev->dvb->frontend = dvb_attach(s5h1411_attach,
600                                                &xc5000_s5h1411_config,
601                                                &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
602
603                 if (dev->dvb->frontend == NULL) {
604                         printk(DRIVER_NAME
605                                ": Failed to attach dummy front end\n");
606                         result = -EINVAL;
607                         goto out_free;
608                 }
609
610                 /* define general-purpose callback pointer */
611                 dvb->frontend->callback = cx231xx_tuner_callback;
612
613                 if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
614                                &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
615                                &cnxt_rdu250_tunerconfig)) {
616                         result = -EINVAL;
617                         goto out_free;
618                 }
619                 break;
620         case CX231XX_BOARD_CNXT_RDE_253S:
621
622                 dev->dvb->frontend = dvb_attach(s5h1432_attach,
623                                         &dvico_s5h1432_config,
624                                         &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
625
626                 if (dev->dvb->frontend == NULL) {
627                         printk(DRIVER_NAME
628                                ": Failed to attach s5h1432 front end\n");
629                         result = -EINVAL;
630                         goto out_free;
631                 }
632
633                 /* define general-purpose callback pointer */
634                 dvb->frontend->callback = cx231xx_tuner_callback;
635
636                 if (!dvb_attach(tda18271_attach, dev->dvb->frontend,
637                                0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
638                                &cnxt_rde253s_tunerconfig)) {
639                         result = -EINVAL;
640                         goto out_free;
641                 }
642                 break;
643         case CX231XX_BOARD_CNXT_RDU_253S:
644
645                 dev->dvb->frontend = dvb_attach(s5h1411_attach,
646                                                &tda18271_s5h1411_config,
647                                                &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
648
649                 if (dev->dvb->frontend == NULL) {
650                         printk(DRIVER_NAME
651                                ": Failed to attach dummy front end\n");
652                         result = -EINVAL;
653                         goto out_free;
654                 }
655
656                 /* define general-purpose callback pointer */
657                 dvb->frontend->callback = cx231xx_tuner_callback;
658
659                 if (!dvb_attach(tda18271_attach, dev->dvb->frontend,
660                                0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
661                                &cnxt_rde253s_tunerconfig)) {
662                         result = -EINVAL;
663                         goto out_free;
664                 }
665                 break;
666         case CX231XX_BOARD_HAUPPAUGE_EXETER:
667
668                 printk(KERN_INFO "%s: looking for tuner / demod on i2c bus: %d\n",
669                        __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap));
670
671                 dev->dvb->frontend = dvb_attach(lgdt3305_attach,
672                                                 &hcw_lgdt3305_config,
673                                                 &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap);
674
675                 if (dev->dvb->frontend == NULL) {
676                         printk(DRIVER_NAME
677                                ": Failed to attach LG3305 front end\n");
678                         result = -EINVAL;
679                         goto out_free;
680                 }
681
682                 /* define general-purpose callback pointer */
683                 dvb->frontend->callback = cx231xx_tuner_callback;
684
685                 dvb_attach(tda18271_attach, dev->dvb->frontend,
686                            0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
687                            &hcw_tda18271_config);
688                 break;
689
690
691         default:
692                 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
693                        " isn't supported yet\n", dev->name);
694                 break;
695         }
696         if (NULL == dvb->frontend) {
697                 printk(KERN_ERR
698                        "%s/2: frontend initialization failed\n", dev->name);
699                 result = -EINVAL;
700                 goto out_free;
701         }
702
703         /* register everything */
704         result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
705
706         if (result < 0)
707                 goto out_free;
708
709
710         printk(KERN_INFO "Successfully loaded cx231xx-dvb\n");
711
712 ret:
713         cx231xx_set_mode(dev, CX231XX_SUSPEND);
714         mutex_unlock(&dev->lock);
715         return result;
716
717 out_free:
718         kfree(dvb);
719         dev->dvb = NULL;
720         goto ret;
721 }
722
723 static int dvb_fini(struct cx231xx *dev)
724 {
725         if (!dev->board.has_dvb) {
726                 /* This device does not support the extension */
727                 return 0;
728         }
729
730         if (dev->dvb) {
731                 unregister_dvb(dev->dvb);
732                 dev->dvb = NULL;
733         }
734
735         return 0;
736 }
737
738 static struct cx231xx_ops dvb_ops = {
739         .id = CX231XX_DVB,
740         .name = "Cx231xx dvb Extension",
741         .init = dvb_init,
742         .fini = dvb_fini,
743 };
744
745 static int __init cx231xx_dvb_register(void)
746 {
747         return cx231xx_register_extension(&dvb_ops);
748 }
749
750 static void __exit cx231xx_dvb_unregister(void)
751 {
752         cx231xx_unregister_extension(&dvb_ops);
753 }
754
755 module_init(cx231xx_dvb_register);
756 module_exit(cx231xx_dvb_unregister);