FRV: Use generic show_interrupts()
[cris-mirror.git] / drivers / media / video / cx88 / cx88-dvb.c
blob7b8c9d3b6efcc54a349b7584293b36a77384db56
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"
60 #include "ds3000.h"
62 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
63 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
64 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
65 MODULE_LICENSE("GPL");
67 static unsigned int debug;
68 module_param(debug, int, 0644);
69 MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
71 static unsigned int dvb_buf_tscnt = 32;
72 module_param(dvb_buf_tscnt, int, 0644);
73 MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]");
75 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
77 #define dprintk(level,fmt, arg...) if (debug >= level) \
78 printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
80 /* ------------------------------------------------------------------ */
82 static int dvb_buf_setup(struct videobuf_queue *q,
83 unsigned int *count, unsigned int *size)
85 struct cx8802_dev *dev = q->priv_data;
87 dev->ts_packet_size = 188 * 4;
88 dev->ts_packet_count = dvb_buf_tscnt;
90 *size = dev->ts_packet_size * dev->ts_packet_count;
91 *count = dvb_buf_tscnt;
92 return 0;
95 static int dvb_buf_prepare(struct videobuf_queue *q,
96 struct videobuf_buffer *vb, enum v4l2_field field)
98 struct cx8802_dev *dev = q->priv_data;
99 return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
102 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
104 struct cx8802_dev *dev = q->priv_data;
105 cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
108 static void dvb_buf_release(struct videobuf_queue *q,
109 struct videobuf_buffer *vb)
111 cx88_free_buffer(q, (struct cx88_buffer*)vb);
114 static const struct videobuf_queue_ops dvb_qops = {
115 .buf_setup = dvb_buf_setup,
116 .buf_prepare = dvb_buf_prepare,
117 .buf_queue = dvb_buf_queue,
118 .buf_release = dvb_buf_release,
121 /* ------------------------------------------------------------------ */
123 static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
125 struct cx8802_dev *dev= fe->dvb->priv;
126 struct cx8802_driver *drv = NULL;
127 int ret = 0;
128 int fe_id;
130 fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
131 if (!fe_id) {
132 printk(KERN_ERR "%s() No frontend found\n", __func__);
133 return -EINVAL;
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;
147 return ret;
150 static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open)
152 struct videobuf_dvb_frontends *f;
153 struct videobuf_dvb_frontend *fe;
155 if (!core->dvbdev)
156 return;
158 f = &core->dvbdev->frontends;
160 if (!f)
161 return;
163 if (f->gate <= 1) /* undefined or fe0 */
164 fe = videobuf_dvb_get_frontend(f, 1);
165 else
166 fe = videobuf_dvb_get_frontend(f, f->gate);
168 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
169 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
172 /* ------------------------------------------------------------------ */
174 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
176 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
177 static const u8 reset [] = { RESET, 0x80 };
178 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
179 static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
180 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
181 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
183 mt352_write(fe, clock_config, sizeof(clock_config));
184 udelay(200);
185 mt352_write(fe, reset, sizeof(reset));
186 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
188 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
189 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
190 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
191 return 0;
194 static int dvico_dual_demod_init(struct dvb_frontend *fe)
196 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
197 static const u8 reset [] = { RESET, 0x80 };
198 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
199 static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
200 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
201 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
203 mt352_write(fe, clock_config, sizeof(clock_config));
204 udelay(200);
205 mt352_write(fe, reset, sizeof(reset));
206 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
208 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
209 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
210 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
212 return 0;
215 static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
217 static const u8 clock_config [] = { 0x89, 0x38, 0x39 };
218 static const u8 reset [] = { 0x50, 0x80 };
219 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
220 static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
221 0x00, 0xFF, 0x00, 0x40, 0x40 };
222 static const u8 dntv_extra[] = { 0xB5, 0x7A };
223 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
225 mt352_write(fe, clock_config, sizeof(clock_config));
226 udelay(2000);
227 mt352_write(fe, reset, sizeof(reset));
228 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
230 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
231 udelay(2000);
232 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
233 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
235 return 0;
238 static const struct mt352_config dvico_fusionhdtv = {
239 .demod_address = 0x0f,
240 .demod_init = dvico_fusionhdtv_demod_init,
243 static const struct mt352_config dntv_live_dvbt_config = {
244 .demod_address = 0x0f,
245 .demod_init = dntv_live_dvbt_demod_init,
248 static const struct mt352_config dvico_fusionhdtv_dual = {
249 .demod_address = 0x0f,
250 .demod_init = dvico_dual_demod_init,
253 static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
254 .demod_address = (0x1e >> 1),
255 .no_tuner = 1,
256 .if2 = 45600,
259 static struct mb86a16_config twinhan_vp1027 = {
260 .demod_address = 0x08,
263 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
264 static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
266 static const u8 clock_config [] = { 0x89, 0x38, 0x38 };
267 static const u8 reset [] = { 0x50, 0x80 };
268 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
269 static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
270 0x00, 0xFF, 0x00, 0x40, 0x40 };
271 static const u8 dntv_extra[] = { 0xB5, 0x7A };
272 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
274 mt352_write(fe, clock_config, sizeof(clock_config));
275 udelay(2000);
276 mt352_write(fe, reset, sizeof(reset));
277 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
279 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
280 udelay(2000);
281 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
282 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
284 return 0;
287 static const struct mt352_config dntv_live_dvbt_pro_config = {
288 .demod_address = 0x0f,
289 .no_tuner = 1,
290 .demod_init = dntv_live_dvbt_pro_demod_init,
292 #endif
294 static const struct zl10353_config dvico_fusionhdtv_hybrid = {
295 .demod_address = 0x0f,
296 .no_tuner = 1,
299 static const struct zl10353_config dvico_fusionhdtv_xc3028 = {
300 .demod_address = 0x0f,
301 .if2 = 45600,
302 .no_tuner = 1,
305 static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
306 .demod_address = 0x0f,
307 .if2 = 4560,
308 .no_tuner = 1,
309 .demod_init = dvico_fusionhdtv_demod_init,
312 static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
313 .demod_address = 0x0f,
316 static const struct cx22702_config connexant_refboard_config = {
317 .demod_address = 0x43,
318 .output_mode = CX22702_SERIAL_OUTPUT,
321 static const struct cx22702_config hauppauge_hvr_config = {
322 .demod_address = 0x63,
323 .output_mode = CX22702_SERIAL_OUTPUT,
326 static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
328 struct cx8802_dev *dev= fe->dvb->priv;
329 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
330 return 0;
333 static const struct or51132_config pchdtv_hd3000 = {
334 .demod_address = 0x15,
335 .set_ts_params = or51132_set_ts_param,
338 static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
340 struct cx8802_dev *dev= fe->dvb->priv;
341 struct cx88_core *core = dev->core;
343 dprintk(1, "%s: index = %d\n", __func__, index);
344 if (index == 0)
345 cx_clear(MO_GP0_IO, 8);
346 else
347 cx_set(MO_GP0_IO, 8);
348 return 0;
351 static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
353 struct cx8802_dev *dev= fe->dvb->priv;
354 if (is_punctured)
355 dev->ts_gen_cntrl |= 0x04;
356 else
357 dev->ts_gen_cntrl &= ~0x04;
358 return 0;
361 static struct lgdt330x_config fusionhdtv_3_gold = {
362 .demod_address = 0x0e,
363 .demod_chip = LGDT3302,
364 .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
365 .set_ts_params = lgdt330x_set_ts_param,
368 static const struct lgdt330x_config fusionhdtv_5_gold = {
369 .demod_address = 0x0e,
370 .demod_chip = LGDT3303,
371 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
372 .set_ts_params = lgdt330x_set_ts_param,
375 static const struct lgdt330x_config pchdtv_hd5500 = {
376 .demod_address = 0x59,
377 .demod_chip = LGDT3303,
378 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
379 .set_ts_params = lgdt330x_set_ts_param,
382 static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
384 struct cx8802_dev *dev= fe->dvb->priv;
385 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
386 return 0;
389 static const struct nxt200x_config ati_hdtvwonder = {
390 .demod_address = 0x0a,
391 .set_ts_params = nxt200x_set_ts_param,
394 static int cx24123_set_ts_param(struct dvb_frontend* fe,
395 int is_punctured)
397 struct cx8802_dev *dev= fe->dvb->priv;
398 dev->ts_gen_cntrl = 0x02;
399 return 0;
402 static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
403 fe_sec_voltage_t voltage)
405 struct cx8802_dev *dev= fe->dvb->priv;
406 struct cx88_core *core = dev->core;
408 if (voltage == SEC_VOLTAGE_OFF)
409 cx_write(MO_GP0_IO, 0x000006fb);
410 else
411 cx_write(MO_GP0_IO, 0x000006f9);
413 if (core->prev_set_voltage)
414 return core->prev_set_voltage(fe, voltage);
415 return 0;
418 static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
419 fe_sec_voltage_t voltage)
421 struct cx8802_dev *dev= fe->dvb->priv;
422 struct cx88_core *core = dev->core;
424 if (voltage == SEC_VOLTAGE_OFF) {
425 dprintk(1,"LNB Voltage OFF\n");
426 cx_write(MO_GP0_IO, 0x0000efff);
429 if (core->prev_set_voltage)
430 return core->prev_set_voltage(fe, voltage);
431 return 0;
434 static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
435 fe_sec_voltage_t voltage)
437 struct cx8802_dev *dev= fe->dvb->priv;
438 struct cx88_core *core = dev->core;
440 cx_set(MO_GP0_IO, 0x6040);
441 switch (voltage) {
442 case SEC_VOLTAGE_13:
443 cx_clear(MO_GP0_IO, 0x20);
444 break;
445 case SEC_VOLTAGE_18:
446 cx_set(MO_GP0_IO, 0x20);
447 break;
448 case SEC_VOLTAGE_OFF:
449 cx_clear(MO_GP0_IO, 0x20);
450 break;
453 if (core->prev_set_voltage)
454 return core->prev_set_voltage(fe, voltage);
455 return 0;
458 static int vp1027_set_voltage(struct dvb_frontend *fe,
459 fe_sec_voltage_t voltage)
461 struct cx8802_dev *dev = fe->dvb->priv;
462 struct cx88_core *core = dev->core;
464 switch (voltage) {
465 case SEC_VOLTAGE_13:
466 dprintk(1, "LNB SEC Voltage=13\n");
467 cx_write(MO_GP0_IO, 0x00001220);
468 break;
469 case SEC_VOLTAGE_18:
470 dprintk(1, "LNB SEC Voltage=18\n");
471 cx_write(MO_GP0_IO, 0x00001222);
472 break;
473 case SEC_VOLTAGE_OFF:
474 dprintk(1, "LNB Voltage OFF\n");
475 cx_write(MO_GP0_IO, 0x00001230);
476 break;
479 if (core->prev_set_voltage)
480 return core->prev_set_voltage(fe, voltage);
481 return 0;
484 static const struct cx24123_config geniatech_dvbs_config = {
485 .demod_address = 0x55,
486 .set_ts_params = cx24123_set_ts_param,
489 static const struct cx24123_config hauppauge_novas_config = {
490 .demod_address = 0x55,
491 .set_ts_params = cx24123_set_ts_param,
494 static const struct cx24123_config kworld_dvbs_100_config = {
495 .demod_address = 0x15,
496 .set_ts_params = cx24123_set_ts_param,
497 .lnb_polarity = 1,
500 static const struct s5h1409_config pinnacle_pctv_hd_800i_config = {
501 .demod_address = 0x32 >> 1,
502 .output_mode = S5H1409_PARALLEL_OUTPUT,
503 .gpio = S5H1409_GPIO_ON,
504 .qam_if = 44000,
505 .inversion = S5H1409_INVERSION_OFF,
506 .status_mode = S5H1409_DEMODLOCKING,
507 .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
510 static const struct s5h1409_config dvico_hdtv5_pci_nano_config = {
511 .demod_address = 0x32 >> 1,
512 .output_mode = S5H1409_SERIAL_OUTPUT,
513 .gpio = S5H1409_GPIO_OFF,
514 .inversion = S5H1409_INVERSION_OFF,
515 .status_mode = S5H1409_DEMODLOCKING,
516 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
519 static const struct s5h1409_config kworld_atsc_120_config = {
520 .demod_address = 0x32 >> 1,
521 .output_mode = S5H1409_SERIAL_OUTPUT,
522 .gpio = S5H1409_GPIO_OFF,
523 .inversion = S5H1409_INVERSION_OFF,
524 .status_mode = S5H1409_DEMODLOCKING,
525 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
528 static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
529 .i2c_address = 0x64,
530 .if_khz = 5380,
533 static const struct zl10353_config cx88_pinnacle_hybrid_pctv = {
534 .demod_address = (0x1e >> 1),
535 .no_tuner = 1,
536 .if2 = 45600,
539 static const struct zl10353_config cx88_geniatech_x8000_mt = {
540 .demod_address = (0x1e >> 1),
541 .no_tuner = 1,
542 .disable_i2c_gate_ctrl = 1,
545 static const struct s5h1411_config dvico_fusionhdtv7_config = {
546 .output_mode = S5H1411_SERIAL_OUTPUT,
547 .gpio = S5H1411_GPIO_ON,
548 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
549 .qam_if = S5H1411_IF_44000,
550 .vsb_if = S5H1411_IF_44000,
551 .inversion = S5H1411_INVERSION_OFF,
552 .status_mode = S5H1411_DEMODLOCKING
555 static const struct xc5000_config dvico_fusionhdtv7_tuner_config = {
556 .i2c_address = 0xc2 >> 1,
557 .if_khz = 5380,
560 static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
562 struct dvb_frontend *fe;
563 struct videobuf_dvb_frontend *fe0 = NULL;
564 struct xc2028_ctrl ctl;
565 struct xc2028_config cfg = {
566 .i2c_adap = &dev->core->i2c_adap,
567 .i2c_addr = addr,
568 .ctrl = &ctl,
571 /* Get the first frontend */
572 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
573 if (!fe0)
574 return -EINVAL;
576 if (!fe0->dvb.frontend) {
577 printk(KERN_ERR "%s/2: dvb frontend not attached. "
578 "Can't attach xc3028\n",
579 dev->core->name);
580 return -EINVAL;
584 * Some xc3028 devices may be hidden by an I2C gate. This is known
585 * to happen with some s5h1409-based devices.
586 * Now that I2C gate is open, sets up xc3028 configuration
588 cx88_setup_xc3028(dev->core, &ctl);
590 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
591 if (!fe) {
592 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
593 dev->core->name);
594 dvb_frontend_detach(fe0->dvb.frontend);
595 dvb_unregister_frontend(fe0->dvb.frontend);
596 fe0->dvb.frontend = NULL;
597 return -EINVAL;
600 printk(KERN_INFO "%s/2: xc3028 attached\n",
601 dev->core->name);
603 return 0;
606 static int cx24116_set_ts_param(struct dvb_frontend *fe,
607 int is_punctured)
609 struct cx8802_dev *dev = fe->dvb->priv;
610 dev->ts_gen_cntrl = 0x2;
612 return 0;
615 static int stv0900_set_ts_param(struct dvb_frontend *fe,
616 int is_punctured)
618 struct cx8802_dev *dev = fe->dvb->priv;
619 dev->ts_gen_cntrl = 0;
621 return 0;
624 static int cx24116_reset_device(struct dvb_frontend *fe)
626 struct cx8802_dev *dev = fe->dvb->priv;
627 struct cx88_core *core = dev->core;
629 /* Reset the part */
630 /* Put the cx24116 into reset */
631 cx_write(MO_SRST_IO, 0);
632 msleep(10);
633 /* Take the cx24116 out of reset */
634 cx_write(MO_SRST_IO, 1);
635 msleep(10);
637 return 0;
640 static const struct cx24116_config hauppauge_hvr4000_config = {
641 .demod_address = 0x05,
642 .set_ts_params = cx24116_set_ts_param,
643 .reset_device = cx24116_reset_device,
646 static const struct cx24116_config tevii_s460_config = {
647 .demod_address = 0x55,
648 .set_ts_params = cx24116_set_ts_param,
649 .reset_device = cx24116_reset_device,
652 static int ds3000_set_ts_param(struct dvb_frontend *fe,
653 int is_punctured)
655 struct cx8802_dev *dev = fe->dvb->priv;
656 dev->ts_gen_cntrl = 4;
658 return 0;
661 static struct ds3000_config tevii_ds3000_config = {
662 .demod_address = 0x68,
663 .set_ts_params = ds3000_set_ts_param,
666 static const struct stv0900_config prof_7301_stv0900_config = {
667 .demod_address = 0x6a,
668 /* demod_mode = 0,*/
669 .xtal = 27000000,
670 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
671 .diseqc_mode = 2,/* 2/3 PWM */
672 .tun1_maddress = 0,/* 0x60 */
673 .tun1_adc = 0,/* 2 Vpp */
674 .path1_mode = 3,
675 .set_ts_params = stv0900_set_ts_param,
678 static const struct stb6100_config prof_7301_stb6100_config = {
679 .tuner_address = 0x60,
680 .refclock = 27000000,
683 static const struct stv0299_config tevii_tuner_sharp_config = {
684 .demod_address = 0x68,
685 .inittab = sharp_z0194a_inittab,
686 .mclk = 88000000UL,
687 .invert = 1,
688 .skip_reinit = 0,
689 .lock_output = 1,
690 .volt13_op0_op1 = STV0299_VOLT13_OP1,
691 .min_delay_ms = 100,
692 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
693 .set_ts_params = cx24116_set_ts_param,
696 static const struct stv0288_config tevii_tuner_earda_config = {
697 .demod_address = 0x68,
698 .min_delay_ms = 100,
699 .set_ts_params = cx24116_set_ts_param,
702 static int cx8802_alloc_frontends(struct cx8802_dev *dev)
704 struct cx88_core *core = dev->core;
705 struct videobuf_dvb_frontend *fe = NULL;
706 int i;
708 mutex_init(&dev->frontends.lock);
709 INIT_LIST_HEAD(&dev->frontends.felist);
711 if (!core->board.num_frontends)
712 return -ENODEV;
714 printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
715 core->board.num_frontends);
716 for (i = 1; i <= core->board.num_frontends; i++) {
717 fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
718 if (!fe) {
719 printk(KERN_ERR "%s() failed to alloc\n", __func__);
720 videobuf_dvb_dealloc_frontends(&dev->frontends);
721 return -ENOMEM;
724 return 0;
729 static const u8 samsung_smt_7020_inittab[] = {
730 0x01, 0x15,
731 0x02, 0x00,
732 0x03, 0x00,
733 0x04, 0x7D,
734 0x05, 0x0F,
735 0x06, 0x02,
736 0x07, 0x00,
737 0x08, 0x60,
739 0x0A, 0xC2,
740 0x0B, 0x00,
741 0x0C, 0x01,
742 0x0D, 0x81,
743 0x0E, 0x44,
744 0x0F, 0x09,
745 0x10, 0x3C,
746 0x11, 0x84,
747 0x12, 0xDA,
748 0x13, 0x99,
749 0x14, 0x8D,
750 0x15, 0xCE,
751 0x16, 0xE8,
752 0x17, 0x43,
753 0x18, 0x1C,
754 0x19, 0x1B,
755 0x1A, 0x1D,
757 0x1C, 0x12,
758 0x1D, 0x00,
759 0x1E, 0x00,
760 0x1F, 0x00,
761 0x20, 0x00,
762 0x21, 0x00,
763 0x22, 0x00,
764 0x23, 0x00,
766 0x28, 0x02,
767 0x29, 0x28,
768 0x2A, 0x14,
769 0x2B, 0x0F,
770 0x2C, 0x09,
771 0x2D, 0x05,
773 0x31, 0x1F,
774 0x32, 0x19,
775 0x33, 0xFC,
776 0x34, 0x13,
777 0xff, 0xff,
781 static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
782 struct dvb_frontend_parameters *params)
784 struct cx8802_dev *dev = fe->dvb->priv;
785 u8 buf[4];
786 u32 div;
787 struct i2c_msg msg = {
788 .addr = 0x61,
789 .flags = 0,
790 .buf = buf,
791 .len = sizeof(buf) };
793 div = params->frequency / 125;
795 buf[0] = (div >> 8) & 0x7f;
796 buf[1] = div & 0xff;
797 buf[2] = 0x84; /* 0xC4 */
798 buf[3] = 0x00;
800 if (params->frequency < 1500000)
801 buf[3] |= 0x10;
803 if (fe->ops.i2c_gate_ctrl)
804 fe->ops.i2c_gate_ctrl(fe, 1);
806 if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
807 return -EIO;
809 return 0;
812 static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
813 fe_sec_tone_mode_t tone)
815 struct cx8802_dev *dev = fe->dvb->priv;
816 struct cx88_core *core = dev->core;
818 cx_set(MO_GP0_IO, 0x0800);
820 switch (tone) {
821 case SEC_TONE_ON:
822 cx_set(MO_GP0_IO, 0x08);
823 break;
824 case SEC_TONE_OFF:
825 cx_clear(MO_GP0_IO, 0x08);
826 break;
827 default:
828 return -EINVAL;
831 return 0;
834 static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
835 fe_sec_voltage_t voltage)
837 struct cx8802_dev *dev = fe->dvb->priv;
838 struct cx88_core *core = dev->core;
840 u8 data;
841 struct i2c_msg msg = {
842 .addr = 8,
843 .flags = 0,
844 .buf = &data,
845 .len = sizeof(data) };
847 cx_set(MO_GP0_IO, 0x8000);
849 switch (voltage) {
850 case SEC_VOLTAGE_OFF:
851 break;
852 case SEC_VOLTAGE_13:
853 data = ISL6421_EN1 | ISL6421_LLC1;
854 cx_clear(MO_GP0_IO, 0x80);
855 break;
856 case SEC_VOLTAGE_18:
857 data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
858 cx_clear(MO_GP0_IO, 0x80);
859 break;
860 default:
861 return -EINVAL;
864 return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
867 static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
868 u32 srate, u32 ratio)
870 u8 aclk = 0;
871 u8 bclk = 0;
873 if (srate < 1500000) {
874 aclk = 0xb7;
875 bclk = 0x47;
876 } else if (srate < 3000000) {
877 aclk = 0xb7;
878 bclk = 0x4b;
879 } else if (srate < 7000000) {
880 aclk = 0xb7;
881 bclk = 0x4f;
882 } else if (srate < 14000000) {
883 aclk = 0xb7;
884 bclk = 0x53;
885 } else if (srate < 30000000) {
886 aclk = 0xb6;
887 bclk = 0x53;
888 } else if (srate < 45000000) {
889 aclk = 0xb4;
890 bclk = 0x51;
893 stv0299_writereg(fe, 0x13, aclk);
894 stv0299_writereg(fe, 0x14, bclk);
895 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
896 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
897 stv0299_writereg(fe, 0x21, ratio & 0xf0);
899 return 0;
903 static const struct stv0299_config samsung_stv0299_config = {
904 .demod_address = 0x68,
905 .inittab = samsung_smt_7020_inittab,
906 .mclk = 88000000UL,
907 .invert = 0,
908 .skip_reinit = 0,
909 .lock_output = STV0299_LOCKOUTPUT_LK,
910 .volt13_op0_op1 = STV0299_VOLT13_OP1,
911 .min_delay_ms = 100,
912 .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
915 static int dvb_register(struct cx8802_dev *dev)
917 struct cx88_core *core = dev->core;
918 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
919 int mfe_shared = 0; /* bus not shared by default */
921 if (0 != core->i2c_rc) {
922 printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
923 goto frontend_detach;
926 /* Get the first frontend */
927 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
928 if (!fe0)
929 goto frontend_detach;
931 /* multi-frontend gate control is undefined or defaults to fe0 */
932 dev->frontends.gate = 0;
934 /* Sets the gate control callback to be used by i2c command calls */
935 core->gate_ctrl = cx88_dvb_gate_ctrl;
937 /* init frontend(s) */
938 switch (core->boardnr) {
939 case CX88_BOARD_HAUPPAUGE_DVB_T1:
940 fe0->dvb.frontend = dvb_attach(cx22702_attach,
941 &connexant_refboard_config,
942 &core->i2c_adap);
943 if (fe0->dvb.frontend != NULL) {
944 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
945 0x61, &core->i2c_adap,
946 DVB_PLL_THOMSON_DTT759X))
947 goto frontend_detach;
949 break;
950 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
951 case CX88_BOARD_CONEXANT_DVB_T1:
952 case CX88_BOARD_KWORLD_DVB_T_CX22702:
953 case CX88_BOARD_WINFAST_DTV1000:
954 fe0->dvb.frontend = dvb_attach(cx22702_attach,
955 &connexant_refboard_config,
956 &core->i2c_adap);
957 if (fe0->dvb.frontend != NULL) {
958 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
959 0x60, &core->i2c_adap,
960 DVB_PLL_THOMSON_DTT7579))
961 goto frontend_detach;
963 break;
964 case CX88_BOARD_WINFAST_DTV2000H:
965 case CX88_BOARD_WINFAST_DTV2000H_J:
966 case CX88_BOARD_HAUPPAUGE_HVR1100:
967 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
968 case CX88_BOARD_HAUPPAUGE_HVR1300:
969 fe0->dvb.frontend = dvb_attach(cx22702_attach,
970 &hauppauge_hvr_config,
971 &core->i2c_adap);
972 if (fe0->dvb.frontend != NULL) {
973 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
974 &core->i2c_adap, 0x61,
975 TUNER_PHILIPS_FMD1216ME_MK3))
976 goto frontend_detach;
978 break;
979 case CX88_BOARD_HAUPPAUGE_HVR3000:
980 /* MFE frontend 1 */
981 mfe_shared = 1;
982 dev->frontends.gate = 2;
983 /* DVB-S init */
984 fe0->dvb.frontend = dvb_attach(cx24123_attach,
985 &hauppauge_novas_config,
986 &dev->core->i2c_adap);
987 if (fe0->dvb.frontend) {
988 if (!dvb_attach(isl6421_attach,
989 fe0->dvb.frontend,
990 &dev->core->i2c_adap,
991 0x08, ISL6421_DCL, 0x00))
992 goto frontend_detach;
994 /* MFE frontend 2 */
995 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
996 if (!fe1)
997 goto frontend_detach;
998 /* DVB-T init */
999 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1000 &hauppauge_hvr_config,
1001 &dev->core->i2c_adap);
1002 if (fe1->dvb.frontend) {
1003 fe1->dvb.frontend->id = 1;
1004 if (!dvb_attach(simple_tuner_attach,
1005 fe1->dvb.frontend,
1006 &dev->core->i2c_adap,
1007 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1008 goto frontend_detach;
1010 break;
1011 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
1012 fe0->dvb.frontend = dvb_attach(mt352_attach,
1013 &dvico_fusionhdtv,
1014 &core->i2c_adap);
1015 if (fe0->dvb.frontend != NULL) {
1016 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1017 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1018 goto frontend_detach;
1019 break;
1021 /* ZL10353 replaces MT352 on later cards */
1022 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1023 &dvico_fusionhdtv_plus_v1_1,
1024 &core->i2c_adap);
1025 if (fe0->dvb.frontend != NULL) {
1026 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1027 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1028 goto frontend_detach;
1030 break;
1031 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1032 /* The tin box says DEE1601, but it seems to be DTT7579
1033 * compatible, with a slightly different MT352 AGC gain. */
1034 fe0->dvb.frontend = dvb_attach(mt352_attach,
1035 &dvico_fusionhdtv_dual,
1036 &core->i2c_adap);
1037 if (fe0->dvb.frontend != NULL) {
1038 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1039 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1040 goto frontend_detach;
1041 break;
1043 /* ZL10353 replaces MT352 on later cards */
1044 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1045 &dvico_fusionhdtv_plus_v1_1,
1046 &core->i2c_adap);
1047 if (fe0->dvb.frontend != NULL) {
1048 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1049 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1050 goto frontend_detach;
1052 break;
1053 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
1054 fe0->dvb.frontend = dvb_attach(mt352_attach,
1055 &dvico_fusionhdtv,
1056 &core->i2c_adap);
1057 if (fe0->dvb.frontend != NULL) {
1058 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1059 0x61, NULL, DVB_PLL_LG_Z201))
1060 goto frontend_detach;
1062 break;
1063 case CX88_BOARD_KWORLD_DVB_T:
1064 case CX88_BOARD_DNTV_LIVE_DVB_T:
1065 case CX88_BOARD_ADSTECH_DVB_T_PCI:
1066 fe0->dvb.frontend = dvb_attach(mt352_attach,
1067 &dntv_live_dvbt_config,
1068 &core->i2c_adap);
1069 if (fe0->dvb.frontend != NULL) {
1070 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1071 0x61, NULL, DVB_PLL_UNKNOWN_1))
1072 goto frontend_detach;
1074 break;
1075 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
1076 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
1077 /* MT352 is on a secondary I2C bus made from some GPIO lines */
1078 fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
1079 &dev->vp3054->adap);
1080 if (fe0->dvb.frontend != NULL) {
1081 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1082 &core->i2c_adap, 0x61,
1083 TUNER_PHILIPS_FMD1216ME_MK3))
1084 goto frontend_detach;
1086 #else
1087 printk(KERN_ERR "%s/2: built without vp3054 support\n",
1088 core->name);
1089 #endif
1090 break;
1091 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
1092 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1093 &dvico_fusionhdtv_hybrid,
1094 &core->i2c_adap);
1095 if (fe0->dvb.frontend != NULL) {
1096 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1097 &core->i2c_adap, 0x61,
1098 TUNER_THOMSON_FE6600))
1099 goto frontend_detach;
1101 break;
1102 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
1103 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1104 &dvico_fusionhdtv_xc3028,
1105 &core->i2c_adap);
1106 if (fe0->dvb.frontend == NULL)
1107 fe0->dvb.frontend = dvb_attach(mt352_attach,
1108 &dvico_fusionhdtv_mt352_xc3028,
1109 &core->i2c_adap);
1111 * On this board, the demod provides the I2C bus pullup.
1112 * We must not permit gate_ctrl to be performed, or
1113 * the xc3028 cannot communicate on the bus.
1115 if (fe0->dvb.frontend)
1116 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1117 if (attach_xc3028(0x61, dev) < 0)
1118 goto frontend_detach;
1119 break;
1120 case CX88_BOARD_PCHDTV_HD3000:
1121 fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
1122 &core->i2c_adap);
1123 if (fe0->dvb.frontend != NULL) {
1124 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1125 &core->i2c_adap, 0x61,
1126 TUNER_THOMSON_DTT761X))
1127 goto frontend_detach;
1129 break;
1130 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
1131 dev->ts_gen_cntrl = 0x08;
1133 /* Do a hardware reset of chip before using it. */
1134 cx_clear(MO_GP0_IO, 1);
1135 mdelay(100);
1136 cx_set(MO_GP0_IO, 1);
1137 mdelay(200);
1139 /* Select RF connector callback */
1140 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
1141 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1142 &fusionhdtv_3_gold,
1143 &core->i2c_adap);
1144 if (fe0->dvb.frontend != NULL) {
1145 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1146 &core->i2c_adap, 0x61,
1147 TUNER_MICROTUNE_4042FI5))
1148 goto frontend_detach;
1150 break;
1151 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
1152 dev->ts_gen_cntrl = 0x08;
1154 /* Do a hardware reset of chip before using it. */
1155 cx_clear(MO_GP0_IO, 1);
1156 mdelay(100);
1157 cx_set(MO_GP0_IO, 9);
1158 mdelay(200);
1159 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1160 &fusionhdtv_3_gold,
1161 &core->i2c_adap);
1162 if (fe0->dvb.frontend != NULL) {
1163 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1164 &core->i2c_adap, 0x61,
1165 TUNER_THOMSON_DTT761X))
1166 goto frontend_detach;
1168 break;
1169 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
1170 dev->ts_gen_cntrl = 0x08;
1172 /* Do a hardware reset of chip before using it. */
1173 cx_clear(MO_GP0_IO, 1);
1174 mdelay(100);
1175 cx_set(MO_GP0_IO, 1);
1176 mdelay(200);
1177 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1178 &fusionhdtv_5_gold,
1179 &core->i2c_adap);
1180 if (fe0->dvb.frontend != NULL) {
1181 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1182 &core->i2c_adap, 0x61,
1183 TUNER_LG_TDVS_H06XF))
1184 goto frontend_detach;
1185 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1186 &core->i2c_adap, 0x43))
1187 goto frontend_detach;
1189 break;
1190 case CX88_BOARD_PCHDTV_HD5500:
1191 dev->ts_gen_cntrl = 0x08;
1193 /* Do a hardware reset of chip before using it. */
1194 cx_clear(MO_GP0_IO, 1);
1195 mdelay(100);
1196 cx_set(MO_GP0_IO, 1);
1197 mdelay(200);
1198 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1199 &pchdtv_hd5500,
1200 &core->i2c_adap);
1201 if (fe0->dvb.frontend != NULL) {
1202 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1203 &core->i2c_adap, 0x61,
1204 TUNER_LG_TDVS_H06XF))
1205 goto frontend_detach;
1206 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1207 &core->i2c_adap, 0x43))
1208 goto frontend_detach;
1210 break;
1211 case CX88_BOARD_ATI_HDTVWONDER:
1212 fe0->dvb.frontend = dvb_attach(nxt200x_attach,
1213 &ati_hdtvwonder,
1214 &core->i2c_adap);
1215 if (fe0->dvb.frontend != NULL) {
1216 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1217 &core->i2c_adap, 0x61,
1218 TUNER_PHILIPS_TUV1236D))
1219 goto frontend_detach;
1221 break;
1222 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
1223 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
1224 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1225 &hauppauge_novas_config,
1226 &core->i2c_adap);
1227 if (fe0->dvb.frontend) {
1228 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
1229 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
1230 goto frontend_detach;
1232 break;
1233 case CX88_BOARD_KWORLD_DVBS_100:
1234 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1235 &kworld_dvbs_100_config,
1236 &core->i2c_adap);
1237 if (fe0->dvb.frontend) {
1238 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1239 fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
1241 break;
1242 case CX88_BOARD_GENIATECH_DVBS:
1243 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1244 &geniatech_dvbs_config,
1245 &core->i2c_adap);
1246 if (fe0->dvb.frontend) {
1247 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1248 fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
1250 break;
1251 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
1252 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1253 &pinnacle_pctv_hd_800i_config,
1254 &core->i2c_adap);
1255 if (fe0->dvb.frontend != NULL) {
1256 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1257 &core->i2c_adap,
1258 &pinnacle_pctv_hd_800i_tuner_config))
1259 goto frontend_detach;
1261 break;
1262 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
1263 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1264 &dvico_hdtv5_pci_nano_config,
1265 &core->i2c_adap);
1266 if (fe0->dvb.frontend != NULL) {
1267 struct dvb_frontend *fe;
1268 struct xc2028_config cfg = {
1269 .i2c_adap = &core->i2c_adap,
1270 .i2c_addr = 0x61,
1272 static struct xc2028_ctrl ctl = {
1273 .fname = XC2028_DEFAULT_FIRMWARE,
1274 .max_len = 64,
1275 .scode_table = XC3028_FE_OREN538,
1278 fe = dvb_attach(xc2028_attach,
1279 fe0->dvb.frontend, &cfg);
1280 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1281 fe->ops.tuner_ops.set_config(fe, &ctl);
1283 break;
1284 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
1285 case CX88_BOARD_WINFAST_DTV1800H:
1286 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1287 &cx88_pinnacle_hybrid_pctv,
1288 &core->i2c_adap);
1289 if (fe0->dvb.frontend) {
1290 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1291 if (attach_xc3028(0x61, dev) < 0)
1292 goto frontend_detach;
1294 break;
1295 case CX88_BOARD_GENIATECH_X8000_MT:
1296 dev->ts_gen_cntrl = 0x00;
1298 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1299 &cx88_geniatech_x8000_mt,
1300 &core->i2c_adap);
1301 if (attach_xc3028(0x61, dev) < 0)
1302 goto frontend_detach;
1303 break;
1304 case CX88_BOARD_KWORLD_ATSC_120:
1305 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1306 &kworld_atsc_120_config,
1307 &core->i2c_adap);
1308 if (attach_xc3028(0x61, dev) < 0)
1309 goto frontend_detach;
1310 break;
1311 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
1312 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1313 &dvico_fusionhdtv7_config,
1314 &core->i2c_adap);
1315 if (fe0->dvb.frontend != NULL) {
1316 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1317 &core->i2c_adap,
1318 &dvico_fusionhdtv7_tuner_config))
1319 goto frontend_detach;
1321 break;
1322 case CX88_BOARD_HAUPPAUGE_HVR4000:
1323 /* MFE frontend 1 */
1324 mfe_shared = 1;
1325 dev->frontends.gate = 2;
1326 /* DVB-S/S2 Init */
1327 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1328 &hauppauge_hvr4000_config,
1329 &dev->core->i2c_adap);
1330 if (fe0->dvb.frontend) {
1331 if (!dvb_attach(isl6421_attach,
1332 fe0->dvb.frontend,
1333 &dev->core->i2c_adap,
1334 0x08, ISL6421_DCL, 0x00))
1335 goto frontend_detach;
1337 /* MFE frontend 2 */
1338 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1339 if (!fe1)
1340 goto frontend_detach;
1341 /* DVB-T Init */
1342 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1343 &hauppauge_hvr_config,
1344 &dev->core->i2c_adap);
1345 if (fe1->dvb.frontend) {
1346 fe1->dvb.frontend->id = 1;
1347 if (!dvb_attach(simple_tuner_attach,
1348 fe1->dvb.frontend,
1349 &dev->core->i2c_adap,
1350 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1351 goto frontend_detach;
1353 break;
1354 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
1355 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1356 &hauppauge_hvr4000_config,
1357 &dev->core->i2c_adap);
1358 if (fe0->dvb.frontend) {
1359 if (!dvb_attach(isl6421_attach,
1360 fe0->dvb.frontend,
1361 &dev->core->i2c_adap,
1362 0x08, ISL6421_DCL, 0x00))
1363 goto frontend_detach;
1365 break;
1366 case CX88_BOARD_PROF_6200:
1367 case CX88_BOARD_TBS_8910:
1368 case CX88_BOARD_TEVII_S420:
1369 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1370 &tevii_tuner_sharp_config,
1371 &core->i2c_adap);
1372 if (fe0->dvb.frontend != NULL) {
1373 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
1374 &core->i2c_adap, DVB_PLL_OPERA1))
1375 goto frontend_detach;
1376 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1377 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1379 } else {
1380 fe0->dvb.frontend = dvb_attach(stv0288_attach,
1381 &tevii_tuner_earda_config,
1382 &core->i2c_adap);
1383 if (fe0->dvb.frontend != NULL) {
1384 if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
1385 &core->i2c_adap))
1386 goto frontend_detach;
1387 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1388 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1391 break;
1392 case CX88_BOARD_TEVII_S460:
1393 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1394 &tevii_s460_config,
1395 &core->i2c_adap);
1396 if (fe0->dvb.frontend != NULL)
1397 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1398 break;
1399 case CX88_BOARD_TEVII_S464:
1400 fe0->dvb.frontend = dvb_attach(ds3000_attach,
1401 &tevii_ds3000_config,
1402 &core->i2c_adap);
1403 if (fe0->dvb.frontend != NULL)
1404 fe0->dvb.frontend->ops.set_voltage =
1405 tevii_dvbs_set_voltage;
1406 break;
1407 case CX88_BOARD_OMICOM_SS4_PCI:
1408 case CX88_BOARD_TBS_8920:
1409 case CX88_BOARD_PROF_7300:
1410 case CX88_BOARD_SATTRADE_ST4200:
1411 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1412 &hauppauge_hvr4000_config,
1413 &core->i2c_adap);
1414 if (fe0->dvb.frontend != NULL)
1415 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1416 break;
1417 case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
1418 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1419 &cx88_terratec_cinergy_ht_pci_mkii_config,
1420 &core->i2c_adap);
1421 if (fe0->dvb.frontend) {
1422 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1423 if (attach_xc3028(0x61, dev) < 0)
1424 goto frontend_detach;
1426 break;
1427 case CX88_BOARD_PROF_7301:{
1428 struct dvb_tuner_ops *tuner_ops = NULL;
1430 fe0->dvb.frontend = dvb_attach(stv0900_attach,
1431 &prof_7301_stv0900_config,
1432 &core->i2c_adap, 0);
1433 if (fe0->dvb.frontend != NULL) {
1434 if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
1435 &prof_7301_stb6100_config,
1436 &core->i2c_adap))
1437 goto frontend_detach;
1439 tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
1440 tuner_ops->set_frequency = stb6100_set_freq;
1441 tuner_ops->get_frequency = stb6100_get_freq;
1442 tuner_ops->set_bandwidth = stb6100_set_bandw;
1443 tuner_ops->get_bandwidth = stb6100_get_bandw;
1445 core->prev_set_voltage =
1446 fe0->dvb.frontend->ops.set_voltage;
1447 fe0->dvb.frontend->ops.set_voltage =
1448 tevii_dvbs_set_voltage;
1450 break;
1452 case CX88_BOARD_SAMSUNG_SMT_7020:
1453 dev->ts_gen_cntrl = 0x08;
1455 cx_set(MO_GP0_IO, 0x0101);
1457 cx_clear(MO_GP0_IO, 0x01);
1458 mdelay(100);
1459 cx_set(MO_GP0_IO, 0x01);
1460 mdelay(200);
1462 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1463 &samsung_stv0299_config,
1464 &dev->core->i2c_adap);
1465 if (fe0->dvb.frontend) {
1466 fe0->dvb.frontend->ops.tuner_ops.set_params =
1467 samsung_smt_7020_tuner_set_params;
1468 fe0->dvb.frontend->tuner_priv =
1469 &dev->core->i2c_adap;
1470 fe0->dvb.frontend->ops.set_voltage =
1471 samsung_smt_7020_set_voltage;
1472 fe0->dvb.frontend->ops.set_tone =
1473 samsung_smt_7020_set_tone;
1476 break;
1477 case CX88_BOARD_TWINHAN_VP1027_DVBS:
1478 dev->ts_gen_cntrl = 0x00;
1479 fe0->dvb.frontend = dvb_attach(mb86a16_attach,
1480 &twinhan_vp1027,
1481 &core->i2c_adap);
1482 if (fe0->dvb.frontend) {
1483 core->prev_set_voltage =
1484 fe0->dvb.frontend->ops.set_voltage;
1485 fe0->dvb.frontend->ops.set_voltage =
1486 vp1027_set_voltage;
1488 break;
1490 default:
1491 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1492 core->name);
1493 break;
1496 if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
1497 printk(KERN_ERR
1498 "%s/2: frontend initialization failed\n",
1499 core->name);
1500 goto frontend_detach;
1502 /* define general-purpose callback pointer */
1503 fe0->dvb.frontend->callback = cx88_tuner_callback;
1505 /* Ensure all frontends negotiate bus access */
1506 fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1507 if (fe1)
1508 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1510 /* Put the analog decoder in standby to keep it quiet */
1511 call_all(core, core, s_power, 0);
1513 /* register everything */
1514 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1515 &dev->pci->dev, adapter_nr, mfe_shared, NULL);
1517 frontend_detach:
1518 core->gate_ctrl = NULL;
1519 videobuf_dvb_dealloc_frontends(&dev->frontends);
1520 return -EINVAL;
1523 /* ----------------------------------------------------------- */
1525 /* CX8802 MPEG -> mini driver - We have been given the hardware */
1526 static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
1528 struct cx88_core *core = drv->core;
1529 int err = 0;
1530 dprintk( 1, "%s\n", __func__);
1532 switch (core->boardnr) {
1533 case CX88_BOARD_HAUPPAUGE_HVR1300:
1534 /* We arrive here with either the cx23416 or the cx22702
1535 * on the bus. Take the bus from the cx23416 and enable the
1536 * cx22702 demod
1538 /* Toggle reset on cx22702 leaving i2c active */
1539 cx_set(MO_GP0_IO, 0x00000080);
1540 udelay(1000);
1541 cx_clear(MO_GP0_IO, 0x00000080);
1542 udelay(50);
1543 cx_set(MO_GP0_IO, 0x00000080);
1544 udelay(1000);
1545 /* enable the cx22702 pins */
1546 cx_clear(MO_GP0_IO, 0x00000004);
1547 udelay(1000);
1548 break;
1550 case CX88_BOARD_HAUPPAUGE_HVR3000:
1551 case CX88_BOARD_HAUPPAUGE_HVR4000:
1552 /* Toggle reset on cx22702 leaving i2c active */
1553 cx_set(MO_GP0_IO, 0x00000080);
1554 udelay(1000);
1555 cx_clear(MO_GP0_IO, 0x00000080);
1556 udelay(50);
1557 cx_set(MO_GP0_IO, 0x00000080);
1558 udelay(1000);
1559 switch (core->dvbdev->frontends.active_fe_id) {
1560 case 1: /* DVB-S/S2 Enabled */
1561 /* tri-state the cx22702 pins */
1562 cx_set(MO_GP0_IO, 0x00000004);
1563 /* Take the cx24116/cx24123 out of reset */
1564 cx_write(MO_SRST_IO, 1);
1565 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1566 break;
1567 case 2: /* DVB-T Enabled */
1568 /* Put the cx24116/cx24123 into reset */
1569 cx_write(MO_SRST_IO, 0);
1570 /* enable the cx22702 pins */
1571 cx_clear(MO_GP0_IO, 0x00000004);
1572 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1573 break;
1575 udelay(1000);
1576 break;
1578 default:
1579 err = -ENODEV;
1581 return err;
1584 /* CX8802 MPEG -> mini driver - We no longer have the hardware */
1585 static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
1587 struct cx88_core *core = drv->core;
1588 int err = 0;
1589 dprintk( 1, "%s\n", __func__);
1591 switch (core->boardnr) {
1592 case CX88_BOARD_HAUPPAUGE_HVR1300:
1593 /* Do Nothing, leave the cx22702 on the bus. */
1594 break;
1595 case CX88_BOARD_HAUPPAUGE_HVR3000:
1596 case CX88_BOARD_HAUPPAUGE_HVR4000:
1597 break;
1598 default:
1599 err = -ENODEV;
1601 return err;
1604 static int cx8802_dvb_probe(struct cx8802_driver *drv)
1606 struct cx88_core *core = drv->core;
1607 struct cx8802_dev *dev = drv->core->dvbdev;
1608 int err;
1609 struct videobuf_dvb_frontend *fe;
1610 int i;
1612 dprintk( 1, "%s\n", __func__);
1613 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1614 core->boardnr,
1615 core->name,
1616 core->pci_bus,
1617 core->pci_slot);
1619 err = -ENODEV;
1620 if (!(core->board.mpeg & CX88_MPEG_DVB))
1621 goto fail_core;
1623 /* If vp3054 isn't enabled, a stub will just return 0 */
1624 err = vp3054_i2c_probe(dev);
1625 if (0 != err)
1626 goto fail_core;
1628 /* dvb stuff */
1629 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1630 dev->ts_gen_cntrl = 0x0c;
1632 err = cx8802_alloc_frontends(dev);
1633 if (err)
1634 goto fail_core;
1636 err = -ENODEV;
1637 for (i = 1; i <= core->board.num_frontends; i++) {
1638 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
1639 if (fe == NULL) {
1640 printk(KERN_ERR "%s() failed to get frontend(%d)\n",
1641 __func__, i);
1642 goto fail_probe;
1644 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
1645 &dev->pci->dev, &dev->slock,
1646 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1647 V4L2_FIELD_TOP,
1648 sizeof(struct cx88_buffer),
1649 dev, NULL);
1650 /* init struct videobuf_dvb */
1651 fe->dvb.name = dev->core->name;
1654 err = dvb_register(dev);
1655 if (err)
1656 /* frontends/adapter de-allocated in dvb_register */
1657 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
1658 core->name, err);
1659 return err;
1660 fail_probe:
1661 videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends);
1662 fail_core:
1663 return err;
1666 static int cx8802_dvb_remove(struct cx8802_driver *drv)
1668 struct cx88_core *core = drv->core;
1669 struct cx8802_dev *dev = drv->core->dvbdev;
1671 dprintk( 1, "%s\n", __func__);
1673 videobuf_dvb_unregister_bus(&dev->frontends);
1675 vp3054_i2c_remove(dev);
1677 core->gate_ctrl = NULL;
1679 return 0;
1682 static struct cx8802_driver cx8802_dvb_driver = {
1683 .type_id = CX88_MPEG_DVB,
1684 .hw_access = CX8802_DRVCTL_SHARED,
1685 .probe = cx8802_dvb_probe,
1686 .remove = cx8802_dvb_remove,
1687 .advise_acquire = cx8802_dvb_advise_acquire,
1688 .advise_release = cx8802_dvb_advise_release,
1691 static int __init dvb_init(void)
1693 printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n",
1694 (CX88_VERSION_CODE >> 16) & 0xff,
1695 (CX88_VERSION_CODE >> 8) & 0xff,
1696 CX88_VERSION_CODE & 0xff);
1697 #ifdef SNAPSHOT
1698 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
1699 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1700 #endif
1701 return cx8802_register_driver(&cx8802_dvb_driver);
1704 static void __exit dvb_fini(void)
1706 cx8802_unregister_driver(&cx8802_dvb_driver);
1709 module_init(dvb_init);
1710 module_exit(dvb_fini);
1713 * Local variables:
1714 * c-basic-offset: 8
1715 * compile-command: "make DVB=1"
1716 * End: