cx88: fix locking of sub-driver operations
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / video / cx88 / cx88-dvb.c
blob5eccd0211e79f81420fe8ddc149a444e30636157
1 /*
3 * device driver for Conexant 2388x based TV cards
4 * MPEG Transport Stream (DVB) routines
6 * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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.
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.
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.
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>
32 #include "cx88.h"
33 #include "dvb-pll.h"
34 #include <media/v4l2-common.h>
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 #include "stv0900.h"
57 #include "stb6100.h"
58 #include "stb6100_proc.h"
59 #include "mb86a16.h"
61 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
62 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
63 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
64 MODULE_LICENSE("GPL");
66 static unsigned int debug;
67 module_param(debug, int, 0644);
68 MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
70 static unsigned int dvb_buf_tscnt = 32;
71 module_param(dvb_buf_tscnt, int, 0644);
72 MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]");
74 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
76 #define dprintk(level,fmt, arg...) if (debug >= level) \
77 printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
79 /* ------------------------------------------------------------------ */
81 static int dvb_buf_setup(struct videobuf_queue *q,
82 unsigned int *count, unsigned int *size)
84 struct cx8802_dev *dev = q->priv_data;
86 dev->ts_packet_size = 188 * 4;
87 dev->ts_packet_count = dvb_buf_tscnt;
89 *size = dev->ts_packet_size * dev->ts_packet_count;
90 *count = dvb_buf_tscnt;
91 return 0;
94 static int dvb_buf_prepare(struct videobuf_queue *q,
95 struct videobuf_buffer *vb, enum v4l2_field field)
97 struct cx8802_dev *dev = q->priv_data;
98 return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
101 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
103 struct cx8802_dev *dev = q->priv_data;
104 cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
107 static void dvb_buf_release(struct videobuf_queue *q,
108 struct videobuf_buffer *vb)
110 cx88_free_buffer(q, (struct cx88_buffer*)vb);
113 static const struct videobuf_queue_ops dvb_qops = {
114 .buf_setup = dvb_buf_setup,
115 .buf_prepare = dvb_buf_prepare,
116 .buf_queue = dvb_buf_queue,
117 .buf_release = dvb_buf_release,
120 /* ------------------------------------------------------------------ */
122 static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
124 struct cx8802_dev *dev= fe->dvb->priv;
125 struct cx8802_driver *drv = NULL;
126 int ret = 0;
127 int fe_id;
129 fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
130 if (!fe_id) {
131 printk(KERN_ERR "%s() No frontend found\n", __func__);
132 return -EINVAL;
135 mutex_lock(&dev->core->lock);
136 drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
137 if (drv) {
138 if (acquire){
139 dev->frontends.active_fe_id = fe_id;
140 ret = drv->request_acquire(drv);
141 } else {
142 ret = drv->request_release(drv);
143 dev->frontends.active_fe_id = 0;
146 mutex_unlock(&dev->core->lock);
148 return ret;
151 static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open)
153 struct videobuf_dvb_frontends *f;
154 struct videobuf_dvb_frontend *fe;
156 if (!core->dvbdev)
157 return;
159 f = &core->dvbdev->frontends;
161 if (!f)
162 return;
164 if (f->gate <= 1) /* undefined or fe0 */
165 fe = videobuf_dvb_get_frontend(f, 1);
166 else
167 fe = videobuf_dvb_get_frontend(f, f->gate);
169 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
170 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
173 /* ------------------------------------------------------------------ */
175 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
177 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
178 static const u8 reset [] = { RESET, 0x80 };
179 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
180 static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
181 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
182 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
184 mt352_write(fe, clock_config, sizeof(clock_config));
185 udelay(200);
186 mt352_write(fe, reset, sizeof(reset));
187 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
189 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
190 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
191 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
192 return 0;
195 static int dvico_dual_demod_init(struct dvb_frontend *fe)
197 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
198 static const u8 reset [] = { RESET, 0x80 };
199 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
200 static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
201 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
202 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
204 mt352_write(fe, clock_config, sizeof(clock_config));
205 udelay(200);
206 mt352_write(fe, reset, sizeof(reset));
207 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
209 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
210 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
211 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
213 return 0;
216 static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
218 static const u8 clock_config [] = { 0x89, 0x38, 0x39 };
219 static const u8 reset [] = { 0x50, 0x80 };
220 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
221 static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
222 0x00, 0xFF, 0x00, 0x40, 0x40 };
223 static const u8 dntv_extra[] = { 0xB5, 0x7A };
224 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
226 mt352_write(fe, clock_config, sizeof(clock_config));
227 udelay(2000);
228 mt352_write(fe, reset, sizeof(reset));
229 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
231 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
232 udelay(2000);
233 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
234 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
236 return 0;
239 static const struct mt352_config dvico_fusionhdtv = {
240 .demod_address = 0x0f,
241 .demod_init = dvico_fusionhdtv_demod_init,
244 static const struct mt352_config dntv_live_dvbt_config = {
245 .demod_address = 0x0f,
246 .demod_init = dntv_live_dvbt_demod_init,
249 static const struct mt352_config dvico_fusionhdtv_dual = {
250 .demod_address = 0x0f,
251 .demod_init = dvico_dual_demod_init,
254 static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
255 .demod_address = (0x1e >> 1),
256 .no_tuner = 1,
257 .if2 = 45600,
260 static struct mb86a16_config twinhan_vp1027 = {
261 .demod_address = 0x08,
264 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
265 static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
267 static const u8 clock_config [] = { 0x89, 0x38, 0x38 };
268 static const u8 reset [] = { 0x50, 0x80 };
269 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
270 static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
271 0x00, 0xFF, 0x00, 0x40, 0x40 };
272 static const u8 dntv_extra[] = { 0xB5, 0x7A };
273 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
275 mt352_write(fe, clock_config, sizeof(clock_config));
276 udelay(2000);
277 mt352_write(fe, reset, sizeof(reset));
278 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
280 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
281 udelay(2000);
282 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
283 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
285 return 0;
288 static const struct mt352_config dntv_live_dvbt_pro_config = {
289 .demod_address = 0x0f,
290 .no_tuner = 1,
291 .demod_init = dntv_live_dvbt_pro_demod_init,
293 #endif
295 static const struct zl10353_config dvico_fusionhdtv_hybrid = {
296 .demod_address = 0x0f,
297 .no_tuner = 1,
300 static const struct zl10353_config dvico_fusionhdtv_xc3028 = {
301 .demod_address = 0x0f,
302 .if2 = 45600,
303 .no_tuner = 1,
306 static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
307 .demod_address = 0x0f,
308 .if2 = 4560,
309 .no_tuner = 1,
310 .demod_init = dvico_fusionhdtv_demod_init,
313 static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
314 .demod_address = 0x0f,
317 static const struct cx22702_config connexant_refboard_config = {
318 .demod_address = 0x43,
319 .output_mode = CX22702_SERIAL_OUTPUT,
322 static const struct cx22702_config hauppauge_hvr_config = {
323 .demod_address = 0x63,
324 .output_mode = CX22702_SERIAL_OUTPUT,
327 static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
329 struct cx8802_dev *dev= fe->dvb->priv;
330 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
331 return 0;
334 static const struct or51132_config pchdtv_hd3000 = {
335 .demod_address = 0x15,
336 .set_ts_params = or51132_set_ts_param,
339 static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
341 struct cx8802_dev *dev= fe->dvb->priv;
342 struct cx88_core *core = dev->core;
344 dprintk(1, "%s: index = %d\n", __func__, index);
345 if (index == 0)
346 cx_clear(MO_GP0_IO, 8);
347 else
348 cx_set(MO_GP0_IO, 8);
349 return 0;
352 static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
354 struct cx8802_dev *dev= fe->dvb->priv;
355 if (is_punctured)
356 dev->ts_gen_cntrl |= 0x04;
357 else
358 dev->ts_gen_cntrl &= ~0x04;
359 return 0;
362 static struct lgdt330x_config fusionhdtv_3_gold = {
363 .demod_address = 0x0e,
364 .demod_chip = LGDT3302,
365 .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
366 .set_ts_params = lgdt330x_set_ts_param,
369 static const struct lgdt330x_config fusionhdtv_5_gold = {
370 .demod_address = 0x0e,
371 .demod_chip = LGDT3303,
372 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
373 .set_ts_params = lgdt330x_set_ts_param,
376 static const struct lgdt330x_config pchdtv_hd5500 = {
377 .demod_address = 0x59,
378 .demod_chip = LGDT3303,
379 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
380 .set_ts_params = lgdt330x_set_ts_param,
383 static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
385 struct cx8802_dev *dev= fe->dvb->priv;
386 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
387 return 0;
390 static const struct nxt200x_config ati_hdtvwonder = {
391 .demod_address = 0x0a,
392 .set_ts_params = nxt200x_set_ts_param,
395 static int cx24123_set_ts_param(struct dvb_frontend* fe,
396 int is_punctured)
398 struct cx8802_dev *dev= fe->dvb->priv;
399 dev->ts_gen_cntrl = 0x02;
400 return 0;
403 static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
404 fe_sec_voltage_t voltage)
406 struct cx8802_dev *dev= fe->dvb->priv;
407 struct cx88_core *core = dev->core;
409 if (voltage == SEC_VOLTAGE_OFF)
410 cx_write(MO_GP0_IO, 0x000006fb);
411 else
412 cx_write(MO_GP0_IO, 0x000006f9);
414 if (core->prev_set_voltage)
415 return core->prev_set_voltage(fe, voltage);
416 return 0;
419 static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
420 fe_sec_voltage_t voltage)
422 struct cx8802_dev *dev= fe->dvb->priv;
423 struct cx88_core *core = dev->core;
425 if (voltage == SEC_VOLTAGE_OFF) {
426 dprintk(1,"LNB Voltage OFF\n");
427 cx_write(MO_GP0_IO, 0x0000efff);
430 if (core->prev_set_voltage)
431 return core->prev_set_voltage(fe, voltage);
432 return 0;
435 static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
436 fe_sec_voltage_t voltage)
438 struct cx8802_dev *dev= fe->dvb->priv;
439 struct cx88_core *core = dev->core;
441 cx_set(MO_GP0_IO, 0x6040);
442 switch (voltage) {
443 case SEC_VOLTAGE_13:
444 cx_clear(MO_GP0_IO, 0x20);
445 break;
446 case SEC_VOLTAGE_18:
447 cx_set(MO_GP0_IO, 0x20);
448 break;
449 case SEC_VOLTAGE_OFF:
450 cx_clear(MO_GP0_IO, 0x20);
451 break;
454 if (core->prev_set_voltage)
455 return core->prev_set_voltage(fe, voltage);
456 return 0;
459 static int vp1027_set_voltage(struct dvb_frontend *fe,
460 fe_sec_voltage_t voltage)
462 struct cx8802_dev *dev = fe->dvb->priv;
463 struct cx88_core *core = dev->core;
465 switch (voltage) {
466 case SEC_VOLTAGE_13:
467 dprintk(1, "LNB SEC Voltage=13\n");
468 cx_write(MO_GP0_IO, 0x00001220);
469 break;
470 case SEC_VOLTAGE_18:
471 dprintk(1, "LNB SEC Voltage=18\n");
472 cx_write(MO_GP0_IO, 0x00001222);
473 break;
474 case SEC_VOLTAGE_OFF:
475 dprintk(1, "LNB Voltage OFF\n");
476 cx_write(MO_GP0_IO, 0x00001230);
477 break;
480 if (core->prev_set_voltage)
481 return core->prev_set_voltage(fe, voltage);
482 return 0;
485 static const struct cx24123_config geniatech_dvbs_config = {
486 .demod_address = 0x55,
487 .set_ts_params = cx24123_set_ts_param,
490 static const struct cx24123_config hauppauge_novas_config = {
491 .demod_address = 0x55,
492 .set_ts_params = cx24123_set_ts_param,
495 static const struct cx24123_config kworld_dvbs_100_config = {
496 .demod_address = 0x15,
497 .set_ts_params = cx24123_set_ts_param,
498 .lnb_polarity = 1,
501 static const struct s5h1409_config pinnacle_pctv_hd_800i_config = {
502 .demod_address = 0x32 >> 1,
503 .output_mode = S5H1409_PARALLEL_OUTPUT,
504 .gpio = S5H1409_GPIO_ON,
505 .qam_if = 44000,
506 .inversion = S5H1409_INVERSION_OFF,
507 .status_mode = S5H1409_DEMODLOCKING,
508 .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
511 static const struct s5h1409_config dvico_hdtv5_pci_nano_config = {
512 .demod_address = 0x32 >> 1,
513 .output_mode = S5H1409_SERIAL_OUTPUT,
514 .gpio = S5H1409_GPIO_OFF,
515 .inversion = S5H1409_INVERSION_OFF,
516 .status_mode = S5H1409_DEMODLOCKING,
517 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
520 static const struct s5h1409_config kworld_atsc_120_config = {
521 .demod_address = 0x32 >> 1,
522 .output_mode = S5H1409_SERIAL_OUTPUT,
523 .gpio = S5H1409_GPIO_OFF,
524 .inversion = S5H1409_INVERSION_OFF,
525 .status_mode = S5H1409_DEMODLOCKING,
526 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
529 static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
530 .i2c_address = 0x64,
531 .if_khz = 5380,
534 static const struct zl10353_config cx88_pinnacle_hybrid_pctv = {
535 .demod_address = (0x1e >> 1),
536 .no_tuner = 1,
537 .if2 = 45600,
540 static const struct zl10353_config cx88_geniatech_x8000_mt = {
541 .demod_address = (0x1e >> 1),
542 .no_tuner = 1,
543 .disable_i2c_gate_ctrl = 1,
546 static const struct s5h1411_config dvico_fusionhdtv7_config = {
547 .output_mode = S5H1411_SERIAL_OUTPUT,
548 .gpio = S5H1411_GPIO_ON,
549 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
550 .qam_if = S5H1411_IF_44000,
551 .vsb_if = S5H1411_IF_44000,
552 .inversion = S5H1411_INVERSION_OFF,
553 .status_mode = S5H1411_DEMODLOCKING
556 static const struct xc5000_config dvico_fusionhdtv7_tuner_config = {
557 .i2c_address = 0xc2 >> 1,
558 .if_khz = 5380,
561 static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
563 struct dvb_frontend *fe;
564 struct videobuf_dvb_frontend *fe0 = NULL;
565 struct xc2028_ctrl ctl;
566 struct xc2028_config cfg = {
567 .i2c_adap = &dev->core->i2c_adap,
568 .i2c_addr = addr,
569 .ctrl = &ctl,
572 /* Get the first frontend */
573 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
574 if (!fe0)
575 return -EINVAL;
577 if (!fe0->dvb.frontend) {
578 printk(KERN_ERR "%s/2: dvb frontend not attached. "
579 "Can't attach xc3028\n",
580 dev->core->name);
581 return -EINVAL;
585 * Some xc3028 devices may be hidden by an I2C gate. This is known
586 * to happen with some s5h1409-based devices.
587 * Now that I2C gate is open, sets up xc3028 configuration
589 cx88_setup_xc3028(dev->core, &ctl);
591 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
592 if (!fe) {
593 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
594 dev->core->name);
595 dvb_frontend_detach(fe0->dvb.frontend);
596 dvb_unregister_frontend(fe0->dvb.frontend);
597 fe0->dvb.frontend = NULL;
598 return -EINVAL;
601 printk(KERN_INFO "%s/2: xc3028 attached\n",
602 dev->core->name);
604 return 0;
607 static int cx24116_set_ts_param(struct dvb_frontend *fe,
608 int is_punctured)
610 struct cx8802_dev *dev = fe->dvb->priv;
611 dev->ts_gen_cntrl = 0x2;
613 return 0;
616 static int stv0900_set_ts_param(struct dvb_frontend *fe,
617 int is_punctured)
619 struct cx8802_dev *dev = fe->dvb->priv;
620 dev->ts_gen_cntrl = 0;
622 return 0;
625 static int cx24116_reset_device(struct dvb_frontend *fe)
627 struct cx8802_dev *dev = fe->dvb->priv;
628 struct cx88_core *core = dev->core;
630 /* Reset the part */
631 /* Put the cx24116 into reset */
632 cx_write(MO_SRST_IO, 0);
633 msleep(10);
634 /* Take the cx24116 out of reset */
635 cx_write(MO_SRST_IO, 1);
636 msleep(10);
638 return 0;
641 static const struct cx24116_config hauppauge_hvr4000_config = {
642 .demod_address = 0x05,
643 .set_ts_params = cx24116_set_ts_param,
644 .reset_device = cx24116_reset_device,
647 static const struct cx24116_config tevii_s460_config = {
648 .demod_address = 0x55,
649 .set_ts_params = cx24116_set_ts_param,
650 .reset_device = cx24116_reset_device,
653 static const struct stv0900_config prof_7301_stv0900_config = {
654 .demod_address = 0x6a,
655 /* demod_mode = 0,*/
656 .xtal = 27000000,
657 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
658 .diseqc_mode = 2,/* 2/3 PWM */
659 .tun1_maddress = 0,/* 0x60 */
660 .tun1_adc = 0,/* 2 Vpp */
661 .path1_mode = 3,
662 .set_ts_params = stv0900_set_ts_param,
665 static const struct stb6100_config prof_7301_stb6100_config = {
666 .tuner_address = 0x60,
667 .refclock = 27000000,
670 static const struct stv0299_config tevii_tuner_sharp_config = {
671 .demod_address = 0x68,
672 .inittab = sharp_z0194a_inittab,
673 .mclk = 88000000UL,
674 .invert = 1,
675 .skip_reinit = 0,
676 .lock_output = 1,
677 .volt13_op0_op1 = STV0299_VOLT13_OP1,
678 .min_delay_ms = 100,
679 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
680 .set_ts_params = cx24116_set_ts_param,
683 static const struct stv0288_config tevii_tuner_earda_config = {
684 .demod_address = 0x68,
685 .min_delay_ms = 100,
686 .set_ts_params = cx24116_set_ts_param,
689 static int cx8802_alloc_frontends(struct cx8802_dev *dev)
691 struct cx88_core *core = dev->core;
692 struct videobuf_dvb_frontend *fe = NULL;
693 int i;
695 mutex_init(&dev->frontends.lock);
696 INIT_LIST_HEAD(&dev->frontends.felist);
698 if (!core->board.num_frontends)
699 return -ENODEV;
701 printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
702 core->board.num_frontends);
703 for (i = 1; i <= core->board.num_frontends; i++) {
704 fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
705 if (!fe) {
706 printk(KERN_ERR "%s() failed to alloc\n", __func__);
707 videobuf_dvb_dealloc_frontends(&dev->frontends);
708 return -ENOMEM;
711 return 0;
716 static const u8 samsung_smt_7020_inittab[] = {
717 0x01, 0x15,
718 0x02, 0x00,
719 0x03, 0x00,
720 0x04, 0x7D,
721 0x05, 0x0F,
722 0x06, 0x02,
723 0x07, 0x00,
724 0x08, 0x60,
726 0x0A, 0xC2,
727 0x0B, 0x00,
728 0x0C, 0x01,
729 0x0D, 0x81,
730 0x0E, 0x44,
731 0x0F, 0x09,
732 0x10, 0x3C,
733 0x11, 0x84,
734 0x12, 0xDA,
735 0x13, 0x99,
736 0x14, 0x8D,
737 0x15, 0xCE,
738 0x16, 0xE8,
739 0x17, 0x43,
740 0x18, 0x1C,
741 0x19, 0x1B,
742 0x1A, 0x1D,
744 0x1C, 0x12,
745 0x1D, 0x00,
746 0x1E, 0x00,
747 0x1F, 0x00,
748 0x20, 0x00,
749 0x21, 0x00,
750 0x22, 0x00,
751 0x23, 0x00,
753 0x28, 0x02,
754 0x29, 0x28,
755 0x2A, 0x14,
756 0x2B, 0x0F,
757 0x2C, 0x09,
758 0x2D, 0x05,
760 0x31, 0x1F,
761 0x32, 0x19,
762 0x33, 0xFC,
763 0x34, 0x13,
764 0xff, 0xff,
768 static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
769 struct dvb_frontend_parameters *params)
771 struct cx8802_dev *dev = fe->dvb->priv;
772 u8 buf[4];
773 u32 div;
774 struct i2c_msg msg = {
775 .addr = 0x61,
776 .flags = 0,
777 .buf = buf,
778 .len = sizeof(buf) };
780 div = params->frequency / 125;
782 buf[0] = (div >> 8) & 0x7f;
783 buf[1] = div & 0xff;
784 buf[2] = 0x84; /* 0xC4 */
785 buf[3] = 0x00;
787 if (params->frequency < 1500000)
788 buf[3] |= 0x10;
790 if (fe->ops.i2c_gate_ctrl)
791 fe->ops.i2c_gate_ctrl(fe, 1);
793 if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
794 return -EIO;
796 return 0;
799 static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
800 fe_sec_tone_mode_t tone)
802 struct cx8802_dev *dev = fe->dvb->priv;
803 struct cx88_core *core = dev->core;
805 cx_set(MO_GP0_IO, 0x0800);
807 switch (tone) {
808 case SEC_TONE_ON:
809 cx_set(MO_GP0_IO, 0x08);
810 break;
811 case SEC_TONE_OFF:
812 cx_clear(MO_GP0_IO, 0x08);
813 break;
814 default:
815 return -EINVAL;
818 return 0;
821 static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
822 fe_sec_voltage_t voltage)
824 struct cx8802_dev *dev = fe->dvb->priv;
825 struct cx88_core *core = dev->core;
827 u8 data;
828 struct i2c_msg msg = {
829 .addr = 8,
830 .flags = 0,
831 .buf = &data,
832 .len = sizeof(data) };
834 cx_set(MO_GP0_IO, 0x8000);
836 switch (voltage) {
837 case SEC_VOLTAGE_OFF:
838 break;
839 case SEC_VOLTAGE_13:
840 data = ISL6421_EN1 | ISL6421_LLC1;
841 cx_clear(MO_GP0_IO, 0x80);
842 break;
843 case SEC_VOLTAGE_18:
844 data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
845 cx_clear(MO_GP0_IO, 0x80);
846 break;
847 default:
848 return -EINVAL;
851 return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
854 static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
855 u32 srate, u32 ratio)
857 u8 aclk = 0;
858 u8 bclk = 0;
860 if (srate < 1500000) {
861 aclk = 0xb7;
862 bclk = 0x47;
863 } else if (srate < 3000000) {
864 aclk = 0xb7;
865 bclk = 0x4b;
866 } else if (srate < 7000000) {
867 aclk = 0xb7;
868 bclk = 0x4f;
869 } else if (srate < 14000000) {
870 aclk = 0xb7;
871 bclk = 0x53;
872 } else if (srate < 30000000) {
873 aclk = 0xb6;
874 bclk = 0x53;
875 } else if (srate < 45000000) {
876 aclk = 0xb4;
877 bclk = 0x51;
880 stv0299_writereg(fe, 0x13, aclk);
881 stv0299_writereg(fe, 0x14, bclk);
882 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
883 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
884 stv0299_writereg(fe, 0x21, ratio & 0xf0);
886 return 0;
890 static const struct stv0299_config samsung_stv0299_config = {
891 .demod_address = 0x68,
892 .inittab = samsung_smt_7020_inittab,
893 .mclk = 88000000UL,
894 .invert = 0,
895 .skip_reinit = 0,
896 .lock_output = STV0299_LOCKOUTPUT_LK,
897 .volt13_op0_op1 = STV0299_VOLT13_OP1,
898 .min_delay_ms = 100,
899 .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
902 static int dvb_register(struct cx8802_dev *dev)
904 struct cx88_core *core = dev->core;
905 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
906 int mfe_shared = 0; /* bus not shared by default */
908 if (0 != core->i2c_rc) {
909 printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
910 goto frontend_detach;
913 /* Get the first frontend */
914 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
915 if (!fe0)
916 goto frontend_detach;
918 /* multi-frontend gate control is undefined or defaults to fe0 */
919 dev->frontends.gate = 0;
921 /* Sets the gate control callback to be used by i2c command calls */
922 core->gate_ctrl = cx88_dvb_gate_ctrl;
924 /* init frontend(s) */
925 switch (core->boardnr) {
926 case CX88_BOARD_HAUPPAUGE_DVB_T1:
927 fe0->dvb.frontend = dvb_attach(cx22702_attach,
928 &connexant_refboard_config,
929 &core->i2c_adap);
930 if (fe0->dvb.frontend != NULL) {
931 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
932 0x61, &core->i2c_adap,
933 DVB_PLL_THOMSON_DTT759X))
934 goto frontend_detach;
936 break;
937 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
938 case CX88_BOARD_CONEXANT_DVB_T1:
939 case CX88_BOARD_KWORLD_DVB_T_CX22702:
940 case CX88_BOARD_WINFAST_DTV1000:
941 fe0->dvb.frontend = dvb_attach(cx22702_attach,
942 &connexant_refboard_config,
943 &core->i2c_adap);
944 if (fe0->dvb.frontend != NULL) {
945 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
946 0x60, &core->i2c_adap,
947 DVB_PLL_THOMSON_DTT7579))
948 goto frontend_detach;
950 break;
951 case CX88_BOARD_WINFAST_DTV2000H:
952 case CX88_BOARD_WINFAST_DTV2000H_J:
953 case CX88_BOARD_HAUPPAUGE_HVR1100:
954 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
955 case CX88_BOARD_HAUPPAUGE_HVR1300:
956 fe0->dvb.frontend = dvb_attach(cx22702_attach,
957 &hauppauge_hvr_config,
958 &core->i2c_adap);
959 if (fe0->dvb.frontend != NULL) {
960 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
961 &core->i2c_adap, 0x61,
962 TUNER_PHILIPS_FMD1216ME_MK3))
963 goto frontend_detach;
965 break;
966 case CX88_BOARD_HAUPPAUGE_HVR3000:
967 /* MFE frontend 1 */
968 mfe_shared = 1;
969 dev->frontends.gate = 2;
970 /* DVB-S init */
971 fe0->dvb.frontend = dvb_attach(cx24123_attach,
972 &hauppauge_novas_config,
973 &dev->core->i2c_adap);
974 if (fe0->dvb.frontend) {
975 if (!dvb_attach(isl6421_attach,
976 fe0->dvb.frontend,
977 &dev->core->i2c_adap,
978 0x08, ISL6421_DCL, 0x00))
979 goto frontend_detach;
981 /* MFE frontend 2 */
982 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
983 if (!fe1)
984 goto frontend_detach;
985 /* DVB-T init */
986 fe1->dvb.frontend = dvb_attach(cx22702_attach,
987 &hauppauge_hvr_config,
988 &dev->core->i2c_adap);
989 if (fe1->dvb.frontend) {
990 fe1->dvb.frontend->id = 1;
991 if (!dvb_attach(simple_tuner_attach,
992 fe1->dvb.frontend,
993 &dev->core->i2c_adap,
994 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
995 goto frontend_detach;
997 break;
998 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
999 fe0->dvb.frontend = dvb_attach(mt352_attach,
1000 &dvico_fusionhdtv,
1001 &core->i2c_adap);
1002 if (fe0->dvb.frontend != NULL) {
1003 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1004 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1005 goto frontend_detach;
1006 break;
1008 /* ZL10353 replaces MT352 on later cards */
1009 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1010 &dvico_fusionhdtv_plus_v1_1,
1011 &core->i2c_adap);
1012 if (fe0->dvb.frontend != NULL) {
1013 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1014 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1015 goto frontend_detach;
1017 break;
1018 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1019 /* The tin box says DEE1601, but it seems to be DTT7579
1020 * compatible, with a slightly different MT352 AGC gain. */
1021 fe0->dvb.frontend = dvb_attach(mt352_attach,
1022 &dvico_fusionhdtv_dual,
1023 &core->i2c_adap);
1024 if (fe0->dvb.frontend != NULL) {
1025 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1026 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1027 goto frontend_detach;
1028 break;
1030 /* ZL10353 replaces MT352 on later cards */
1031 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1032 &dvico_fusionhdtv_plus_v1_1,
1033 &core->i2c_adap);
1034 if (fe0->dvb.frontend != NULL) {
1035 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1036 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1037 goto frontend_detach;
1039 break;
1040 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
1041 fe0->dvb.frontend = dvb_attach(mt352_attach,
1042 &dvico_fusionhdtv,
1043 &core->i2c_adap);
1044 if (fe0->dvb.frontend != NULL) {
1045 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1046 0x61, NULL, DVB_PLL_LG_Z201))
1047 goto frontend_detach;
1049 break;
1050 case CX88_BOARD_KWORLD_DVB_T:
1051 case CX88_BOARD_DNTV_LIVE_DVB_T:
1052 case CX88_BOARD_ADSTECH_DVB_T_PCI:
1053 fe0->dvb.frontend = dvb_attach(mt352_attach,
1054 &dntv_live_dvbt_config,
1055 &core->i2c_adap);
1056 if (fe0->dvb.frontend != NULL) {
1057 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1058 0x61, NULL, DVB_PLL_UNKNOWN_1))
1059 goto frontend_detach;
1061 break;
1062 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
1063 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
1064 /* MT352 is on a secondary I2C bus made from some GPIO lines */
1065 fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
1066 &dev->vp3054->adap);
1067 if (fe0->dvb.frontend != NULL) {
1068 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1069 &core->i2c_adap, 0x61,
1070 TUNER_PHILIPS_FMD1216ME_MK3))
1071 goto frontend_detach;
1073 #else
1074 printk(KERN_ERR "%s/2: built without vp3054 support\n",
1075 core->name);
1076 #endif
1077 break;
1078 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
1079 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1080 &dvico_fusionhdtv_hybrid,
1081 &core->i2c_adap);
1082 if (fe0->dvb.frontend != NULL) {
1083 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1084 &core->i2c_adap, 0x61,
1085 TUNER_THOMSON_FE6600))
1086 goto frontend_detach;
1088 break;
1089 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
1090 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1091 &dvico_fusionhdtv_xc3028,
1092 &core->i2c_adap);
1093 if (fe0->dvb.frontend == NULL)
1094 fe0->dvb.frontend = dvb_attach(mt352_attach,
1095 &dvico_fusionhdtv_mt352_xc3028,
1096 &core->i2c_adap);
1098 * On this board, the demod provides the I2C bus pullup.
1099 * We must not permit gate_ctrl to be performed, or
1100 * the xc3028 cannot communicate on the bus.
1102 if (fe0->dvb.frontend)
1103 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1104 if (attach_xc3028(0x61, dev) < 0)
1105 goto frontend_detach;
1106 break;
1107 case CX88_BOARD_PCHDTV_HD3000:
1108 fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
1109 &core->i2c_adap);
1110 if (fe0->dvb.frontend != NULL) {
1111 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1112 &core->i2c_adap, 0x61,
1113 TUNER_THOMSON_DTT761X))
1114 goto frontend_detach;
1116 break;
1117 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
1118 dev->ts_gen_cntrl = 0x08;
1120 /* Do a hardware reset of chip before using it. */
1121 cx_clear(MO_GP0_IO, 1);
1122 mdelay(100);
1123 cx_set(MO_GP0_IO, 1);
1124 mdelay(200);
1126 /* Select RF connector callback */
1127 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
1128 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1129 &fusionhdtv_3_gold,
1130 &core->i2c_adap);
1131 if (fe0->dvb.frontend != NULL) {
1132 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1133 &core->i2c_adap, 0x61,
1134 TUNER_MICROTUNE_4042FI5))
1135 goto frontend_detach;
1137 break;
1138 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
1139 dev->ts_gen_cntrl = 0x08;
1141 /* Do a hardware reset of chip before using it. */
1142 cx_clear(MO_GP0_IO, 1);
1143 mdelay(100);
1144 cx_set(MO_GP0_IO, 9);
1145 mdelay(200);
1146 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1147 &fusionhdtv_3_gold,
1148 &core->i2c_adap);
1149 if (fe0->dvb.frontend != NULL) {
1150 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1151 &core->i2c_adap, 0x61,
1152 TUNER_THOMSON_DTT761X))
1153 goto frontend_detach;
1155 break;
1156 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
1157 dev->ts_gen_cntrl = 0x08;
1159 /* Do a hardware reset of chip before using it. */
1160 cx_clear(MO_GP0_IO, 1);
1161 mdelay(100);
1162 cx_set(MO_GP0_IO, 1);
1163 mdelay(200);
1164 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1165 &fusionhdtv_5_gold,
1166 &core->i2c_adap);
1167 if (fe0->dvb.frontend != NULL) {
1168 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1169 &core->i2c_adap, 0x61,
1170 TUNER_LG_TDVS_H06XF))
1171 goto frontend_detach;
1172 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1173 &core->i2c_adap, 0x43))
1174 goto frontend_detach;
1176 break;
1177 case CX88_BOARD_PCHDTV_HD5500:
1178 dev->ts_gen_cntrl = 0x08;
1180 /* Do a hardware reset of chip before using it. */
1181 cx_clear(MO_GP0_IO, 1);
1182 mdelay(100);
1183 cx_set(MO_GP0_IO, 1);
1184 mdelay(200);
1185 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1186 &pchdtv_hd5500,
1187 &core->i2c_adap);
1188 if (fe0->dvb.frontend != NULL) {
1189 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1190 &core->i2c_adap, 0x61,
1191 TUNER_LG_TDVS_H06XF))
1192 goto frontend_detach;
1193 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1194 &core->i2c_adap, 0x43))
1195 goto frontend_detach;
1197 break;
1198 case CX88_BOARD_ATI_HDTVWONDER:
1199 fe0->dvb.frontend = dvb_attach(nxt200x_attach,
1200 &ati_hdtvwonder,
1201 &core->i2c_adap);
1202 if (fe0->dvb.frontend != NULL) {
1203 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1204 &core->i2c_adap, 0x61,
1205 TUNER_PHILIPS_TUV1236D))
1206 goto frontend_detach;
1208 break;
1209 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
1210 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
1211 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1212 &hauppauge_novas_config,
1213 &core->i2c_adap);
1214 if (fe0->dvb.frontend) {
1215 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
1216 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
1217 goto frontend_detach;
1219 break;
1220 case CX88_BOARD_KWORLD_DVBS_100:
1221 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1222 &kworld_dvbs_100_config,
1223 &core->i2c_adap);
1224 if (fe0->dvb.frontend) {
1225 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1226 fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
1228 break;
1229 case CX88_BOARD_GENIATECH_DVBS:
1230 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1231 &geniatech_dvbs_config,
1232 &core->i2c_adap);
1233 if (fe0->dvb.frontend) {
1234 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1235 fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
1237 break;
1238 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
1239 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1240 &pinnacle_pctv_hd_800i_config,
1241 &core->i2c_adap);
1242 if (fe0->dvb.frontend != NULL) {
1243 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1244 &core->i2c_adap,
1245 &pinnacle_pctv_hd_800i_tuner_config))
1246 goto frontend_detach;
1248 break;
1249 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
1250 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1251 &dvico_hdtv5_pci_nano_config,
1252 &core->i2c_adap);
1253 if (fe0->dvb.frontend != NULL) {
1254 struct dvb_frontend *fe;
1255 struct xc2028_config cfg = {
1256 .i2c_adap = &core->i2c_adap,
1257 .i2c_addr = 0x61,
1259 static struct xc2028_ctrl ctl = {
1260 .fname = XC2028_DEFAULT_FIRMWARE,
1261 .max_len = 64,
1262 .scode_table = XC3028_FE_OREN538,
1265 fe = dvb_attach(xc2028_attach,
1266 fe0->dvb.frontend, &cfg);
1267 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1268 fe->ops.tuner_ops.set_config(fe, &ctl);
1270 break;
1271 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
1272 case CX88_BOARD_WINFAST_DTV1800H:
1273 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1274 &cx88_pinnacle_hybrid_pctv,
1275 &core->i2c_adap);
1276 if (fe0->dvb.frontend) {
1277 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1278 if (attach_xc3028(0x61, dev) < 0)
1279 goto frontend_detach;
1281 break;
1282 case CX88_BOARD_GENIATECH_X8000_MT:
1283 dev->ts_gen_cntrl = 0x00;
1285 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1286 &cx88_geniatech_x8000_mt,
1287 &core->i2c_adap);
1288 if (attach_xc3028(0x61, dev) < 0)
1289 goto frontend_detach;
1290 break;
1291 case CX88_BOARD_KWORLD_ATSC_120:
1292 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1293 &kworld_atsc_120_config,
1294 &core->i2c_adap);
1295 if (attach_xc3028(0x61, dev) < 0)
1296 goto frontend_detach;
1297 break;
1298 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
1299 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1300 &dvico_fusionhdtv7_config,
1301 &core->i2c_adap);
1302 if (fe0->dvb.frontend != NULL) {
1303 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1304 &core->i2c_adap,
1305 &dvico_fusionhdtv7_tuner_config))
1306 goto frontend_detach;
1308 break;
1309 case CX88_BOARD_HAUPPAUGE_HVR4000:
1310 /* MFE frontend 1 */
1311 mfe_shared = 1;
1312 dev->frontends.gate = 2;
1313 /* DVB-S/S2 Init */
1314 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1315 &hauppauge_hvr4000_config,
1316 &dev->core->i2c_adap);
1317 if (fe0->dvb.frontend) {
1318 if (!dvb_attach(isl6421_attach,
1319 fe0->dvb.frontend,
1320 &dev->core->i2c_adap,
1321 0x08, ISL6421_DCL, 0x00))
1322 goto frontend_detach;
1324 /* MFE frontend 2 */
1325 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1326 if (!fe1)
1327 goto frontend_detach;
1328 /* DVB-T Init */
1329 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1330 &hauppauge_hvr_config,
1331 &dev->core->i2c_adap);
1332 if (fe1->dvb.frontend) {
1333 fe1->dvb.frontend->id = 1;
1334 if (!dvb_attach(simple_tuner_attach,
1335 fe1->dvb.frontend,
1336 &dev->core->i2c_adap,
1337 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1338 goto frontend_detach;
1340 break;
1341 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
1342 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1343 &hauppauge_hvr4000_config,
1344 &dev->core->i2c_adap);
1345 if (fe0->dvb.frontend) {
1346 if (!dvb_attach(isl6421_attach,
1347 fe0->dvb.frontend,
1348 &dev->core->i2c_adap,
1349 0x08, ISL6421_DCL, 0x00))
1350 goto frontend_detach;
1352 break;
1353 case CX88_BOARD_PROF_6200:
1354 case CX88_BOARD_TBS_8910:
1355 case CX88_BOARD_TEVII_S420:
1356 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1357 &tevii_tuner_sharp_config,
1358 &core->i2c_adap);
1359 if (fe0->dvb.frontend != NULL) {
1360 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
1361 &core->i2c_adap, DVB_PLL_OPERA1))
1362 goto frontend_detach;
1363 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1364 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1366 } else {
1367 fe0->dvb.frontend = dvb_attach(stv0288_attach,
1368 &tevii_tuner_earda_config,
1369 &core->i2c_adap);
1370 if (fe0->dvb.frontend != NULL) {
1371 if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
1372 &core->i2c_adap))
1373 goto frontend_detach;
1374 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1375 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1378 break;
1379 case CX88_BOARD_TEVII_S460:
1380 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1381 &tevii_s460_config,
1382 &core->i2c_adap);
1383 if (fe0->dvb.frontend != NULL)
1384 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1385 break;
1386 case CX88_BOARD_OMICOM_SS4_PCI:
1387 case CX88_BOARD_TBS_8920:
1388 case CX88_BOARD_PROF_7300:
1389 case CX88_BOARD_SATTRADE_ST4200:
1390 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1391 &hauppauge_hvr4000_config,
1392 &core->i2c_adap);
1393 if (fe0->dvb.frontend != NULL)
1394 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1395 break;
1396 case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
1397 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1398 &cx88_terratec_cinergy_ht_pci_mkii_config,
1399 &core->i2c_adap);
1400 if (fe0->dvb.frontend) {
1401 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1402 if (attach_xc3028(0x61, dev) < 0)
1403 goto frontend_detach;
1405 break;
1406 case CX88_BOARD_PROF_7301:{
1407 struct dvb_tuner_ops *tuner_ops = NULL;
1409 fe0->dvb.frontend = dvb_attach(stv0900_attach,
1410 &prof_7301_stv0900_config,
1411 &core->i2c_adap, 0);
1412 if (fe0->dvb.frontend != NULL) {
1413 if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
1414 &prof_7301_stb6100_config,
1415 &core->i2c_adap))
1416 goto frontend_detach;
1418 tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
1419 tuner_ops->set_frequency = stb6100_set_freq;
1420 tuner_ops->get_frequency = stb6100_get_freq;
1421 tuner_ops->set_bandwidth = stb6100_set_bandw;
1422 tuner_ops->get_bandwidth = stb6100_get_bandw;
1424 core->prev_set_voltage =
1425 fe0->dvb.frontend->ops.set_voltage;
1426 fe0->dvb.frontend->ops.set_voltage =
1427 tevii_dvbs_set_voltage;
1429 break;
1431 case CX88_BOARD_SAMSUNG_SMT_7020:
1432 dev->ts_gen_cntrl = 0x08;
1434 cx_set(MO_GP0_IO, 0x0101);
1436 cx_clear(MO_GP0_IO, 0x01);
1437 mdelay(100);
1438 cx_set(MO_GP0_IO, 0x01);
1439 mdelay(200);
1441 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1442 &samsung_stv0299_config,
1443 &dev->core->i2c_adap);
1444 if (fe0->dvb.frontend) {
1445 fe0->dvb.frontend->ops.tuner_ops.set_params =
1446 samsung_smt_7020_tuner_set_params;
1447 fe0->dvb.frontend->tuner_priv =
1448 &dev->core->i2c_adap;
1449 fe0->dvb.frontend->ops.set_voltage =
1450 samsung_smt_7020_set_voltage;
1451 fe0->dvb.frontend->ops.set_tone =
1452 samsung_smt_7020_set_tone;
1455 break;
1456 case CX88_BOARD_TWINHAN_VP1027_DVBS:
1457 dev->ts_gen_cntrl = 0x00;
1458 fe0->dvb.frontend = dvb_attach(mb86a16_attach,
1459 &twinhan_vp1027,
1460 &core->i2c_adap);
1461 if (fe0->dvb.frontend) {
1462 core->prev_set_voltage =
1463 fe0->dvb.frontend->ops.set_voltage;
1464 fe0->dvb.frontend->ops.set_voltage =
1465 vp1027_set_voltage;
1467 break;
1469 default:
1470 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1471 core->name);
1472 break;
1475 if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
1476 printk(KERN_ERR
1477 "%s/2: frontend initialization failed\n",
1478 core->name);
1479 goto frontend_detach;
1481 /* define general-purpose callback pointer */
1482 fe0->dvb.frontend->callback = cx88_tuner_callback;
1484 /* Ensure all frontends negotiate bus access */
1485 fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1486 if (fe1)
1487 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1489 /* Put the analog decoder in standby to keep it quiet */
1490 call_all(core, core, s_power, 0);
1492 /* register everything */
1493 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1494 &dev->pci->dev, adapter_nr, mfe_shared, NULL);
1496 frontend_detach:
1497 core->gate_ctrl = NULL;
1498 videobuf_dvb_dealloc_frontends(&dev->frontends);
1499 return -EINVAL;
1502 /* ----------------------------------------------------------- */
1504 /* CX8802 MPEG -> mini driver - We have been given the hardware */
1505 static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
1507 struct cx88_core *core = drv->core;
1508 int err = 0;
1509 dprintk( 1, "%s\n", __func__);
1511 switch (core->boardnr) {
1512 case CX88_BOARD_HAUPPAUGE_HVR1300:
1513 /* We arrive here with either the cx23416 or the cx22702
1514 * on the bus. Take the bus from the cx23416 and enable the
1515 * cx22702 demod
1517 /* Toggle reset on cx22702 leaving i2c active */
1518 cx_set(MO_GP0_IO, 0x00000080);
1519 udelay(1000);
1520 cx_clear(MO_GP0_IO, 0x00000080);
1521 udelay(50);
1522 cx_set(MO_GP0_IO, 0x00000080);
1523 udelay(1000);
1524 /* enable the cx22702 pins */
1525 cx_clear(MO_GP0_IO, 0x00000004);
1526 udelay(1000);
1527 break;
1529 case CX88_BOARD_HAUPPAUGE_HVR3000:
1530 case CX88_BOARD_HAUPPAUGE_HVR4000:
1531 /* Toggle reset on cx22702 leaving i2c active */
1532 cx_set(MO_GP0_IO, 0x00000080);
1533 udelay(1000);
1534 cx_clear(MO_GP0_IO, 0x00000080);
1535 udelay(50);
1536 cx_set(MO_GP0_IO, 0x00000080);
1537 udelay(1000);
1538 switch (core->dvbdev->frontends.active_fe_id) {
1539 case 1: /* DVB-S/S2 Enabled */
1540 /* tri-state the cx22702 pins */
1541 cx_set(MO_GP0_IO, 0x00000004);
1542 /* Take the cx24116/cx24123 out of reset */
1543 cx_write(MO_SRST_IO, 1);
1544 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1545 break;
1546 case 2: /* DVB-T Enabled */
1547 /* Put the cx24116/cx24123 into reset */
1548 cx_write(MO_SRST_IO, 0);
1549 /* enable the cx22702 pins */
1550 cx_clear(MO_GP0_IO, 0x00000004);
1551 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1552 break;
1554 udelay(1000);
1555 break;
1557 default:
1558 err = -ENODEV;
1560 return err;
1563 /* CX8802 MPEG -> mini driver - We no longer have the hardware */
1564 static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
1566 struct cx88_core *core = drv->core;
1567 int err = 0;
1568 dprintk( 1, "%s\n", __func__);
1570 switch (core->boardnr) {
1571 case CX88_BOARD_HAUPPAUGE_HVR1300:
1572 /* Do Nothing, leave the cx22702 on the bus. */
1573 break;
1574 case CX88_BOARD_HAUPPAUGE_HVR3000:
1575 case CX88_BOARD_HAUPPAUGE_HVR4000:
1576 break;
1577 default:
1578 err = -ENODEV;
1580 return err;
1583 static int cx8802_dvb_probe(struct cx8802_driver *drv)
1585 struct cx88_core *core = drv->core;
1586 struct cx8802_dev *dev = drv->core->dvbdev;
1587 int err;
1588 struct videobuf_dvb_frontend *fe;
1589 int i;
1591 dprintk( 1, "%s\n", __func__);
1592 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1593 core->boardnr,
1594 core->name,
1595 core->pci_bus,
1596 core->pci_slot);
1598 err = -ENODEV;
1599 if (!(core->board.mpeg & CX88_MPEG_DVB))
1600 goto fail_core;
1602 /* If vp3054 isn't enabled, a stub will just return 0 */
1603 err = vp3054_i2c_probe(dev);
1604 if (0 != err)
1605 goto fail_core;
1607 /* dvb stuff */
1608 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1609 dev->ts_gen_cntrl = 0x0c;
1611 err = cx8802_alloc_frontends(dev);
1612 if (err)
1613 goto fail_core;
1615 err = -ENODEV;
1616 for (i = 1; i <= core->board.num_frontends; i++) {
1617 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
1618 if (fe == NULL) {
1619 printk(KERN_ERR "%s() failed to get frontend(%d)\n",
1620 __func__, i);
1621 goto fail_probe;
1623 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
1624 &dev->pci->dev, &dev->slock,
1625 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1626 V4L2_FIELD_TOP,
1627 sizeof(struct cx88_buffer),
1628 dev, NULL);
1629 /* init struct videobuf_dvb */
1630 fe->dvb.name = dev->core->name;
1633 err = dvb_register(dev);
1634 if (err)
1635 /* frontends/adapter de-allocated in dvb_register */
1636 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
1637 core->name, err);
1638 return err;
1639 fail_probe:
1640 videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends);
1641 fail_core:
1642 return err;
1645 static int cx8802_dvb_remove(struct cx8802_driver *drv)
1647 struct cx88_core *core = drv->core;
1648 struct cx8802_dev *dev = drv->core->dvbdev;
1650 dprintk( 1, "%s\n", __func__);
1652 videobuf_dvb_unregister_bus(&dev->frontends);
1654 vp3054_i2c_remove(dev);
1656 core->gate_ctrl = NULL;
1658 return 0;
1661 static struct cx8802_driver cx8802_dvb_driver = {
1662 .type_id = CX88_MPEG_DVB,
1663 .hw_access = CX8802_DRVCTL_SHARED,
1664 .probe = cx8802_dvb_probe,
1665 .remove = cx8802_dvb_remove,
1666 .advise_acquire = cx8802_dvb_advise_acquire,
1667 .advise_release = cx8802_dvb_advise_release,
1670 static int __init dvb_init(void)
1672 printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n",
1673 (CX88_VERSION_CODE >> 16) & 0xff,
1674 (CX88_VERSION_CODE >> 8) & 0xff,
1675 CX88_VERSION_CODE & 0xff);
1676 #ifdef SNAPSHOT
1677 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
1678 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1679 #endif
1680 return cx8802_register_driver(&cx8802_dvb_driver);
1683 static void __exit dvb_fini(void)
1685 cx8802_unregister_driver(&cx8802_dvb_driver);
1688 module_init(dvb_init);
1689 module_exit(dvb_fini);
1692 * Local variables:
1693 * c-basic-offset: 8
1694 * compile-command: "make DVB=1"
1695 * End: