Merge branch 'fix/asoc' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[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 "s5h1432.h"
32 #include "tda18271.h"
33 #include "s5h1411.h"
34 #include "lgdt3305.h"
35 #include "mb86a20s.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_std_map mb86a20s_tda18271_config = {
92         .dvbt_6   = { .if_freq = 3300, .agc_mode = 3, .std = 4,
93                       .if_lvl = 7, .rfagc_top = 0x37, },
94 };
95
96 static struct tda18271_config cnxt_rde253s_tunerconfig = {
97         .std_map = &cnxt_rde253s_tda18271_std_map,
98         .gate    = TDA18271_GATE_ANALOG,
99 };
100
101 static struct s5h1411_config tda18271_s5h1411_config = {
102         .output_mode   = S5H1411_SERIAL_OUTPUT,
103         .gpio          = S5H1411_GPIO_OFF,
104         .vsb_if        = S5H1411_IF_3250,
105         .qam_if        = S5H1411_IF_4000,
106         .inversion     = S5H1411_INVERSION_ON,
107         .status_mode   = S5H1411_DEMODLOCKING,
108         .mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
109 };
110 static struct s5h1411_config xc5000_s5h1411_config = {
111         .output_mode   = S5H1411_SERIAL_OUTPUT,
112         .gpio          = S5H1411_GPIO_OFF,
113         .vsb_if        = S5H1411_IF_3250,
114         .qam_if        = S5H1411_IF_3250,
115         .inversion     = S5H1411_INVERSION_OFF,
116         .status_mode   = S5H1411_DEMODLOCKING,
117         .mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
118 };
119
120 static struct lgdt3305_config hcw_lgdt3305_config = {
121         .i2c_addr           = 0x0e,
122         .mpeg_mode          = LGDT3305_MPEG_SERIAL,
123         .tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
124         .tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
125         .deny_i2c_rptr      = 1,
126         .spectral_inversion = 1,
127         .qam_if_khz         = 4000,
128         .vsb_if_khz         = 3250,
129 };
130
131 static struct tda18271_std_map hauppauge_tda18271_std_map = {
132         .atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 4,
133                       .if_lvl = 1, .rfagc_top = 0x58, },
134         .qam_6    = { .if_freq = 4000, .agc_mode = 3, .std = 5,
135                       .if_lvl = 1, .rfagc_top = 0x58, },
136 };
137
138 static struct tda18271_config hcw_tda18271_config = {
139         .std_map = &hauppauge_tda18271_std_map,
140         .gate    = TDA18271_GATE_DIGITAL,
141 };
142
143 static const struct mb86a20s_config pv_mb86a20s_config = {
144         .demod_address = 0x10,
145         .is_serial = true,
146 };
147
148 static struct tda18271_config pv_tda18271_config = {
149         .std_map = &mb86a20s_tda18271_config,
150         .gate    = TDA18271_GATE_DIGITAL,
151         .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
152 };
153
154 static inline void print_err_status(struct cx231xx *dev, int packet, int status)
155 {
156         char *errmsg = "Unknown";
157
158         switch (status) {
159         case -ENOENT:
160                 errmsg = "unlinked synchronuously";
161                 break;
162         case -ECONNRESET:
163                 errmsg = "unlinked asynchronuously";
164                 break;
165         case -ENOSR:
166                 errmsg = "Buffer error (overrun)";
167                 break;
168         case -EPIPE:
169                 errmsg = "Stalled (device not responding)";
170                 break;
171         case -EOVERFLOW:
172                 errmsg = "Babble (bad cable?)";
173                 break;
174         case -EPROTO:
175                 errmsg = "Bit-stuff error (bad cable?)";
176                 break;
177         case -EILSEQ:
178                 errmsg = "CRC/Timeout (could be anything)";
179                 break;
180         case -ETIME:
181                 errmsg = "Device does not respond";
182                 break;
183         }
184         if (packet < 0) {
185                 dprintk(1, "URB status %d [%s].\n", status, errmsg);
186         } else {
187                 dprintk(1, "URB packet %d, status %d [%s].\n",
188                         packet, status, errmsg);
189         }
190 }
191
192 static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb)
193 {
194         int i;
195
196         if (!dev)
197                 return 0;
198
199         if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
200                 return 0;
201
202         if (urb->status < 0) {
203                 print_err_status(dev, -1, urb->status);
204                 if (urb->status == -ENOENT)
205                         return 0;
206         }
207
208         for (i = 0; i < urb->number_of_packets; i++) {
209                 int status = urb->iso_frame_desc[i].status;
210
211                 if (status < 0) {
212                         print_err_status(dev, i, status);
213                         if (urb->iso_frame_desc[i].status != -EPROTO)
214                                 continue;
215                 }
216
217                 dvb_dmx_swfilter(&dev->dvb->demux,
218                                  urb->transfer_buffer +
219                                 urb->iso_frame_desc[i].offset,
220                                 urb->iso_frame_desc[i].actual_length);
221         }
222
223         return 0;
224 }
225
226 static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb)
227 {
228         if (!dev)
229                 return 0;
230
231         if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
232                 return 0;
233
234         if (urb->status < 0) {
235                 print_err_status(dev, -1, urb->status);
236                 if (urb->status == -ENOENT)
237                         return 0;
238         }
239
240         /* Feed the transport payload into the kernel demux */
241         dvb_dmx_swfilter(&dev->dvb->demux,
242                 urb->transfer_buffer, urb->actual_length);
243
244         return 0;
245 }
246
247 static int start_streaming(struct cx231xx_dvb *dvb)
248 {
249         int rc;
250         struct cx231xx *dev = dvb->adapter.priv;
251
252         if (dev->USE_ISO) {
253                 cx231xx_info("DVB transfer mode is ISO.\n");
254                 mutex_lock(&dev->i2c_lock);
255                 cx231xx_enable_i2c_port_3(dev, false);
256                 cx231xx_set_alt_setting(dev, INDEX_TS1, 4);
257                 cx231xx_enable_i2c_port_3(dev, true);
258                 mutex_unlock(&dev->i2c_lock);
259                 rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
260                 if (rc < 0)
261                         return rc;
262                 dev->mode_tv = 1;
263                 return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS,
264                                         CX231XX_DVB_NUM_BUFS,
265                                         dev->ts1_mode.max_pkt_size,
266                                         dvb_isoc_copy);
267         } else {
268                 cx231xx_info("DVB transfer mode is BULK.\n");
269                 cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
270                 rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
271                 if (rc < 0)
272                         return rc;
273                 dev->mode_tv = 1;
274                 return cx231xx_init_bulk(dev, CX231XX_DVB_MAX_PACKETS,
275                                         CX231XX_DVB_NUM_BUFS,
276                                         dev->ts1_mode.max_pkt_size,
277                                         dvb_bulk_copy);
278         }
279
280 }
281
282 static int stop_streaming(struct cx231xx_dvb *dvb)
283 {
284         struct cx231xx *dev = dvb->adapter.priv;
285
286         if (dev->USE_ISO)
287                 cx231xx_uninit_isoc(dev);
288         else
289                 cx231xx_uninit_bulk(dev);
290
291         cx231xx_set_mode(dev, CX231XX_SUSPEND);
292
293         return 0;
294 }
295
296 static int start_feed(struct dvb_demux_feed *feed)
297 {
298         struct dvb_demux *demux = feed->demux;
299         struct cx231xx_dvb *dvb = demux->priv;
300         int rc, ret;
301
302         if (!demux->dmx.frontend)
303                 return -EINVAL;
304
305         mutex_lock(&dvb->lock);
306         dvb->nfeeds++;
307         rc = dvb->nfeeds;
308
309         if (dvb->nfeeds == 1) {
310                 ret = start_streaming(dvb);
311                 if (ret < 0)
312                         rc = ret;
313         }
314
315         mutex_unlock(&dvb->lock);
316         return rc;
317 }
318
319 static int stop_feed(struct dvb_demux_feed *feed)
320 {
321         struct dvb_demux *demux = feed->demux;
322         struct cx231xx_dvb *dvb = demux->priv;
323         int err = 0;
324
325         mutex_lock(&dvb->lock);
326         dvb->nfeeds--;
327
328         if (0 == dvb->nfeeds)
329                 err = stop_streaming(dvb);
330
331         mutex_unlock(&dvb->lock);
332         return err;
333 }
334
335 /* ------------------------------------------------------------------ */
336 static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
337 {
338         struct cx231xx *dev = fe->dvb->priv;
339
340         if (acquire)
341                 return cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
342         else
343                 return cx231xx_set_mode(dev, CX231XX_SUSPEND);
344 }
345
346 /* ------------------------------------------------------------------ */
347
348 static struct xc5000_config cnxt_rde250_tunerconfig = {
349         .i2c_address = 0x61,
350         .if_khz = 4000,
351 };
352 static struct xc5000_config cnxt_rdu250_tunerconfig = {
353         .i2c_address = 0x61,
354         .if_khz = 3250,
355 };
356
357 /* ------------------------------------------------------------------ */
358 #if 0
359 static int attach_xc5000(u8 addr, struct cx231xx *dev)
360 {
361
362         struct dvb_frontend *fe;
363         struct xc5000_config cfg;
364
365         memset(&cfg, 0, sizeof(cfg));
366         cfg.i2c_adap = &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap;
367         cfg.i2c_addr = addr;
368
369         if (!dev->dvb->frontend) {
370                 printk(KERN_ERR "%s/2: dvb frontend not attached. "
371                        "Can't attach xc5000\n", dev->name);
372                 return -EINVAL;
373         }
374
375         fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg);
376         if (!fe) {
377                 printk(KERN_ERR "%s/2: xc5000 attach failed\n", dev->name);
378                 dvb_frontend_detach(dev->dvb->frontend);
379                 dev->dvb->frontend = NULL;
380                 return -EINVAL;
381         }
382
383         printk(KERN_INFO "%s/2: xc5000 attached\n", dev->name);
384
385         return 0;
386 }
387 #endif
388
389 int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq)
390 {
391         int status = 0;
392
393         if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
394
395                 struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
396
397                 if (dops->set_analog_params != NULL) {
398                         struct analog_parameters params;
399
400                         params.frequency = freq;
401                         params.std = dev->norm;
402                         params.mode = 0;        /* 0- Air; 1 - cable */
403                         /*params.audmode = ;       */
404
405                         /* Set the analog parameters to set the frequency */
406                         dops->set_analog_params(dev->dvb->frontend, &params);
407                 }
408
409         }
410
411         return status;
412 }
413
414 int cx231xx_reset_analog_tuner(struct cx231xx *dev)
415 {
416         int status = 0;
417
418         if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
419
420                 struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
421
422                 if (dops->init != NULL && !dev->xc_fw_load_done) {
423
424                         cx231xx_info("Reloading firmware for XC5000\n");
425                         status = dops->init(dev->dvb->frontend);
426                         if (status == 0) {
427                                 dev->xc_fw_load_done = 1;
428                                 cx231xx_info
429                                     ("XC5000 firmware download completed\n");
430                         } else {
431                                 dev->xc_fw_load_done = 0;
432                                 cx231xx_info
433                                     ("XC5000 firmware download failed !!!\n");
434                         }
435                 }
436
437         }
438
439         return status;
440 }
441
442 /* ------------------------------------------------------------------ */
443
444 static int register_dvb(struct cx231xx_dvb *dvb,
445                         struct module *module,
446                         struct cx231xx *dev, struct device *device)
447 {
448         int result;
449
450         mutex_init(&dvb->lock);
451
452         /* register adapter */
453         result = dvb_register_adapter(&dvb->adapter, dev->name, module, device,
454                                       adapter_nr);
455         if (result < 0) {
456                 printk(KERN_WARNING
457                        "%s: dvb_register_adapter failed (errno = %d)\n",
458                        dev->name, result);
459                 goto fail_adapter;
460         }
461
462         /* Ensure all frontends negotiate bus access */
463         dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl;
464
465         dvb->adapter.priv = dev;
466
467         /* register frontend */
468         result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
469         if (result < 0) {
470                 printk(KERN_WARNING
471                        "%s: dvb_register_frontend failed (errno = %d)\n",
472                        dev->name, result);
473                 goto fail_frontend;
474         }
475
476         /* register demux stuff */
477         dvb->demux.dmx.capabilities =
478             DMX_TS_FILTERING | DMX_SECTION_FILTERING |
479             DMX_MEMORY_BASED_FILTERING;
480         dvb->demux.priv = dvb;
481         dvb->demux.filternum = 256;
482         dvb->demux.feednum = 256;
483         dvb->demux.start_feed = start_feed;
484         dvb->demux.stop_feed = stop_feed;
485
486         result = dvb_dmx_init(&dvb->demux);
487         if (result < 0) {
488                 printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n",
489                        dev->name, result);
490                 goto fail_dmx;
491         }
492
493         dvb->dmxdev.filternum = 256;
494         dvb->dmxdev.demux = &dvb->demux.dmx;
495         dvb->dmxdev.capabilities = 0;
496         result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
497         if (result < 0) {
498                 printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
499                        dev->name, result);
500                 goto fail_dmxdev;
501         }
502
503         dvb->fe_hw.source = DMX_FRONTEND_0;
504         result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
505         if (result < 0) {
506                 printk(KERN_WARNING
507                        "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
508                        dev->name, result);
509                 goto fail_fe_hw;
510         }
511
512         dvb->fe_mem.source = DMX_MEMORY_FE;
513         result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
514         if (result < 0) {
515                 printk(KERN_WARNING
516                        "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
517                        dev->name, result);
518                 goto fail_fe_mem;
519         }
520
521         result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
522         if (result < 0) {
523                 printk(KERN_WARNING
524                        "%s: connect_frontend failed (errno = %d)\n", dev->name,
525                        result);
526                 goto fail_fe_conn;
527         }
528
529         /* register network adapter */
530         dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
531         return 0;
532
533 fail_fe_conn:
534         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
535 fail_fe_mem:
536         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
537 fail_fe_hw:
538         dvb_dmxdev_release(&dvb->dmxdev);
539 fail_dmxdev:
540         dvb_dmx_release(&dvb->demux);
541 fail_dmx:
542         dvb_unregister_frontend(dvb->frontend);
543 fail_frontend:
544         dvb_frontend_detach(dvb->frontend);
545         dvb_unregister_adapter(&dvb->adapter);
546 fail_adapter:
547         return result;
548 }
549
550 static void unregister_dvb(struct cx231xx_dvb *dvb)
551 {
552         dvb_net_release(&dvb->net);
553         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
554         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
555         dvb_dmxdev_release(&dvb->dmxdev);
556         dvb_dmx_release(&dvb->demux);
557         dvb_unregister_frontend(dvb->frontend);
558         dvb_frontend_detach(dvb->frontend);
559         dvb_unregister_adapter(&dvb->adapter);
560 }
561
562 static int dvb_init(struct cx231xx *dev)
563 {
564         int result = 0;
565         struct cx231xx_dvb *dvb;
566
567         if (!dev->board.has_dvb) {
568                 /* This device does not support the extension */
569                 return 0;
570         }
571
572         dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL);
573
574         if (dvb == NULL) {
575                 printk(KERN_INFO "cx231xx_dvb: memory allocation failed\n");
576                 return -ENOMEM;
577         }
578         dev->dvb = dvb;
579         dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
580         dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;
581
582         mutex_lock(&dev->lock);
583         cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
584         cx231xx_demod_reset(dev);
585         /* init frontend */
586         switch (dev->model) {
587         case CX231XX_BOARD_CNXT_CARRAERA:
588         case CX231XX_BOARD_CNXT_RDE_250:
589
590                 dev->dvb->frontend = dvb_attach(s5h1432_attach,
591                                         &dvico_s5h1432_config,
592                                         &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
593
594                 if (dev->dvb->frontend == NULL) {
595                         printk(DRIVER_NAME
596                                ": Failed to attach s5h1432 front end\n");
597                         result = -EINVAL;
598                         goto out_free;
599                 }
600
601                 /* define general-purpose callback pointer */
602                 dvb->frontend->callback = cx231xx_tuner_callback;
603
604                 if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
605                                &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
606                                &cnxt_rde250_tunerconfig)) {
607                         result = -EINVAL;
608                         goto out_free;
609                 }
610
611                 break;
612         case CX231XX_BOARD_CNXT_SHELBY:
613         case CX231XX_BOARD_CNXT_RDU_250:
614
615                 dev->dvb->frontend = dvb_attach(s5h1411_attach,
616                                                &xc5000_s5h1411_config,
617                                                &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
618
619                 if (dev->dvb->frontend == NULL) {
620                         printk(DRIVER_NAME
621                                ": Failed to attach s5h1411 front end\n");
622                         result = -EINVAL;
623                         goto out_free;
624                 }
625
626                 /* define general-purpose callback pointer */
627                 dvb->frontend->callback = cx231xx_tuner_callback;
628
629                 if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
630                                &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
631                                &cnxt_rdu250_tunerconfig)) {
632                         result = -EINVAL;
633                         goto out_free;
634                 }
635                 break;
636         case CX231XX_BOARD_CNXT_RDE_253S:
637
638                 dev->dvb->frontend = dvb_attach(s5h1432_attach,
639                                         &dvico_s5h1432_config,
640                                         &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
641
642                 if (dev->dvb->frontend == NULL) {
643                         printk(DRIVER_NAME
644                                ": Failed to attach s5h1432 front end\n");
645                         result = -EINVAL;
646                         goto out_free;
647                 }
648
649                 /* define general-purpose callback pointer */
650                 dvb->frontend->callback = cx231xx_tuner_callback;
651
652                 if (!dvb_attach(tda18271_attach, dev->dvb->frontend,
653                                0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
654                                &cnxt_rde253s_tunerconfig)) {
655                         result = -EINVAL;
656                         goto out_free;
657                 }
658                 break;
659         case CX231XX_BOARD_CNXT_RDU_253S:
660
661                 dev->dvb->frontend = dvb_attach(s5h1411_attach,
662                                                &tda18271_s5h1411_config,
663                                                &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
664
665                 if (dev->dvb->frontend == NULL) {
666                         printk(DRIVER_NAME
667                                ": Failed to attach s5h1411 front end\n");
668                         result = -EINVAL;
669                         goto out_free;
670                 }
671
672                 /* define general-purpose callback pointer */
673                 dvb->frontend->callback = cx231xx_tuner_callback;
674
675                 if (!dvb_attach(tda18271_attach, dev->dvb->frontend,
676                                0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
677                                &cnxt_rde253s_tunerconfig)) {
678                         result = -EINVAL;
679                         goto out_free;
680                 }
681                 break;
682         case CX231XX_BOARD_HAUPPAUGE_EXETER:
683
684                 printk(KERN_INFO "%s: looking for tuner / demod on i2c bus: %d\n",
685                        __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap));
686
687                 dev->dvb->frontend = dvb_attach(lgdt3305_attach,
688                                                 &hcw_lgdt3305_config,
689                                                 &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap);
690
691                 if (dev->dvb->frontend == NULL) {
692                         printk(DRIVER_NAME
693                                ": Failed to attach LG3305 front end\n");
694                         result = -EINVAL;
695                         goto out_free;
696                 }
697
698                 /* define general-purpose callback pointer */
699                 dvb->frontend->callback = cx231xx_tuner_callback;
700
701                 dvb_attach(tda18271_attach, dev->dvb->frontend,
702                            0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
703                            &hcw_tda18271_config);
704                 break;
705
706         case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
707
708                 printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n",
709                        __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap));
710
711                 dev->dvb->frontend = dvb_attach(mb86a20s_attach,
712                                                 &pv_mb86a20s_config,
713                                                 &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
714
715                 if (dev->dvb->frontend == NULL) {
716                         printk(DRIVER_NAME
717                                ": Failed to attach mb86a20s demod\n");
718                         result = -EINVAL;
719                         goto out_free;
720                 }
721
722                 /* define general-purpose callback pointer */
723                 dvb->frontend->callback = cx231xx_tuner_callback;
724
725                 dvb_attach(tda18271_attach, dev->dvb->frontend,
726                            0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
727                            &pv_tda18271_config);
728                 break;
729
730         default:
731                 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
732                        " isn't supported yet\n", dev->name);
733                 break;
734         }
735         if (NULL == dvb->frontend) {
736                 printk(KERN_ERR
737                        "%s/2: frontend initialization failed\n", dev->name);
738                 result = -EINVAL;
739                 goto out_free;
740         }
741
742         /* register everything */
743         result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
744
745         if (result < 0)
746                 goto out_free;
747
748
749         printk(KERN_INFO "Successfully loaded cx231xx-dvb\n");
750
751 ret:
752         cx231xx_set_mode(dev, CX231XX_SUSPEND);
753         mutex_unlock(&dev->lock);
754         return result;
755
756 out_free:
757         kfree(dvb);
758         dev->dvb = NULL;
759         goto ret;
760 }
761
762 static int dvb_fini(struct cx231xx *dev)
763 {
764         if (!dev->board.has_dvb) {
765                 /* This device does not support the extension */
766                 return 0;
767         }
768
769         if (dev->dvb) {
770                 unregister_dvb(dev->dvb);
771                 dev->dvb = NULL;
772         }
773
774         return 0;
775 }
776
777 static struct cx231xx_ops dvb_ops = {
778         .id = CX231XX_DVB,
779         .name = "Cx231xx dvb Extension",
780         .init = dvb_init,
781         .fini = dvb_fini,
782 };
783
784 static int __init cx231xx_dvb_register(void)
785 {
786         return cx231xx_register_extension(&dvb_ops);
787 }
788
789 static void __exit cx231xx_dvb_unregister(void)
790 {
791         cx231xx_unregister_extension(&dvb_ops);
792 }
793
794 module_init(cx231xx_dvb_register);
795 module_exit(cx231xx_dvb_unregister);