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>
28 #include <linux/kthread.h>
29 #include <linux/file.h>
30 #include <linux/suspend.h>
34 #include <media/v4l2-common.h>
37 #include "mt352_priv.h"
38 #include "cx88-vp3054-i2c.h"
48 #include "tuner-simple.h"
58 #include "stb6100_proc.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 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
72 #define dprintk(level,fmt, arg...) if (debug >= level) \
73 printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
75 /* ------------------------------------------------------------------ */
77 static int dvb_buf_setup(struct videobuf_queue *q,
78 unsigned int *count, unsigned int *size)
80 struct cx8802_dev *dev = q->priv_data;
82 dev->ts_packet_size = 188 * 4;
83 dev->ts_packet_count = 32;
85 *size = dev->ts_packet_size * dev->ts_packet_count;
90 static int dvb_buf_prepare(struct videobuf_queue *q,
91 struct videobuf_buffer *vb, enum v4l2_field field)
93 struct cx8802_dev *dev = q->priv_data;
94 return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
97 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
99 struct cx8802_dev *dev = q->priv_data;
100 cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
103 static void dvb_buf_release(struct videobuf_queue *q,
104 struct videobuf_buffer *vb)
106 cx88_free_buffer(q, (struct cx88_buffer*)vb);
109 static const struct videobuf_queue_ops dvb_qops = {
110 .buf_setup = dvb_buf_setup,
111 .buf_prepare = dvb_buf_prepare,
112 .buf_queue = dvb_buf_queue,
113 .buf_release = dvb_buf_release,
116 /* ------------------------------------------------------------------ */
118 static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
120 struct cx8802_dev *dev= fe->dvb->priv;
121 struct cx8802_driver *drv = NULL;
125 fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
127 printk(KERN_ERR "%s() No frontend found\n", __func__);
131 drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
134 dev->frontends.active_fe_id = fe_id;
135 ret = drv->request_acquire(drv);
137 ret = drv->request_release(drv);
138 dev->frontends.active_fe_id = 0;
145 static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open)
147 struct videobuf_dvb_frontends *f;
148 struct videobuf_dvb_frontend *fe;
153 f = &core->dvbdev->frontends;
158 if (f->gate <= 1) /* undefined or fe0 */
159 fe = videobuf_dvb_get_frontend(f, 1);
161 fe = videobuf_dvb_get_frontend(f, f->gate);
163 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
164 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
167 /* ------------------------------------------------------------------ */
169 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
171 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
172 static const u8 reset [] = { RESET, 0x80 };
173 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
174 static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
175 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
176 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
178 mt352_write(fe, clock_config, sizeof(clock_config));
180 mt352_write(fe, reset, sizeof(reset));
181 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
183 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
184 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
185 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
189 static int dvico_dual_demod_init(struct dvb_frontend *fe)
191 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
192 static const u8 reset [] = { RESET, 0x80 };
193 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
194 static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
195 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
196 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
198 mt352_write(fe, clock_config, sizeof(clock_config));
200 mt352_write(fe, reset, sizeof(reset));
201 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
203 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
204 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
205 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
210 static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
212 static const u8 clock_config [] = { 0x89, 0x38, 0x39 };
213 static const u8 reset [] = { 0x50, 0x80 };
214 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
215 static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
216 0x00, 0xFF, 0x00, 0x40, 0x40 };
217 static const u8 dntv_extra[] = { 0xB5, 0x7A };
218 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
220 mt352_write(fe, clock_config, sizeof(clock_config));
222 mt352_write(fe, reset, sizeof(reset));
223 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
225 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
227 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
228 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
233 static const struct mt352_config dvico_fusionhdtv = {
234 .demod_address = 0x0f,
235 .demod_init = dvico_fusionhdtv_demod_init,
238 static const struct mt352_config dntv_live_dvbt_config = {
239 .demod_address = 0x0f,
240 .demod_init = dntv_live_dvbt_demod_init,
243 static const struct mt352_config dvico_fusionhdtv_dual = {
244 .demod_address = 0x0f,
245 .demod_init = dvico_dual_demod_init,
248 static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
249 .demod_address = (0x1e >> 1),
254 static struct mb86a16_config twinhan_vp1027 = {
255 .demod_address = 0x08,
258 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
259 static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
261 static const u8 clock_config [] = { 0x89, 0x38, 0x38 };
262 static const u8 reset [] = { 0x50, 0x80 };
263 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
264 static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
265 0x00, 0xFF, 0x00, 0x40, 0x40 };
266 static const u8 dntv_extra[] = { 0xB5, 0x7A };
267 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
269 mt352_write(fe, clock_config, sizeof(clock_config));
271 mt352_write(fe, reset, sizeof(reset));
272 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
274 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
276 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
277 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
282 static const struct mt352_config dntv_live_dvbt_pro_config = {
283 .demod_address = 0x0f,
285 .demod_init = dntv_live_dvbt_pro_demod_init,
289 static const struct zl10353_config dvico_fusionhdtv_hybrid = {
290 .demod_address = 0x0f,
294 static const struct zl10353_config dvico_fusionhdtv_xc3028 = {
295 .demod_address = 0x0f,
300 static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
301 .demod_address = 0x0f,
304 .demod_init = dvico_fusionhdtv_demod_init,
307 static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
308 .demod_address = 0x0f,
311 static const struct cx22702_config connexant_refboard_config = {
312 .demod_address = 0x43,
313 .output_mode = CX22702_SERIAL_OUTPUT,
316 static const struct cx22702_config hauppauge_hvr_config = {
317 .demod_address = 0x63,
318 .output_mode = CX22702_SERIAL_OUTPUT,
321 static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
323 struct cx8802_dev *dev= fe->dvb->priv;
324 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
328 static const struct or51132_config pchdtv_hd3000 = {
329 .demod_address = 0x15,
330 .set_ts_params = or51132_set_ts_param,
333 static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
335 struct cx8802_dev *dev= fe->dvb->priv;
336 struct cx88_core *core = dev->core;
338 dprintk(1, "%s: index = %d\n", __func__, index);
340 cx_clear(MO_GP0_IO, 8);
342 cx_set(MO_GP0_IO, 8);
346 static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
348 struct cx8802_dev *dev= fe->dvb->priv;
350 dev->ts_gen_cntrl |= 0x04;
352 dev->ts_gen_cntrl &= ~0x04;
356 static struct lgdt330x_config fusionhdtv_3_gold = {
357 .demod_address = 0x0e,
358 .demod_chip = LGDT3302,
359 .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
360 .set_ts_params = lgdt330x_set_ts_param,
363 static const struct lgdt330x_config fusionhdtv_5_gold = {
364 .demod_address = 0x0e,
365 .demod_chip = LGDT3303,
366 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
367 .set_ts_params = lgdt330x_set_ts_param,
370 static const struct lgdt330x_config pchdtv_hd5500 = {
371 .demod_address = 0x59,
372 .demod_chip = LGDT3303,
373 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
374 .set_ts_params = lgdt330x_set_ts_param,
377 static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
379 struct cx8802_dev *dev= fe->dvb->priv;
380 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
384 static const struct nxt200x_config ati_hdtvwonder = {
385 .demod_address = 0x0a,
386 .set_ts_params = nxt200x_set_ts_param,
389 static int cx24123_set_ts_param(struct dvb_frontend* fe,
392 struct cx8802_dev *dev= fe->dvb->priv;
393 dev->ts_gen_cntrl = 0x02;
397 static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
398 fe_sec_voltage_t voltage)
400 struct cx8802_dev *dev= fe->dvb->priv;
401 struct cx88_core *core = dev->core;
403 if (voltage == SEC_VOLTAGE_OFF)
404 cx_write(MO_GP0_IO, 0x000006fb);
406 cx_write(MO_GP0_IO, 0x000006f9);
408 if (core->prev_set_voltage)
409 return core->prev_set_voltage(fe, voltage);
413 static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
414 fe_sec_voltage_t voltage)
416 struct cx8802_dev *dev= fe->dvb->priv;
417 struct cx88_core *core = dev->core;
419 if (voltage == SEC_VOLTAGE_OFF) {
420 dprintk(1,"LNB Voltage OFF\n");
421 cx_write(MO_GP0_IO, 0x0000efff);
424 if (core->prev_set_voltage)
425 return core->prev_set_voltage(fe, voltage);
429 static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
430 fe_sec_voltage_t voltage)
432 struct cx8802_dev *dev= fe->dvb->priv;
433 struct cx88_core *core = dev->core;
435 cx_set(MO_GP0_IO, 0x6040);
438 cx_clear(MO_GP0_IO, 0x20);
441 cx_set(MO_GP0_IO, 0x20);
443 case SEC_VOLTAGE_OFF:
444 cx_clear(MO_GP0_IO, 0x20);
448 if (core->prev_set_voltage)
449 return core->prev_set_voltage(fe, voltage);
453 static int vp1027_set_voltage(struct dvb_frontend *fe,
454 fe_sec_voltage_t voltage)
456 struct cx8802_dev *dev = fe->dvb->priv;
457 struct cx88_core *core = dev->core;
461 dprintk(1, "LNB SEC Voltage=13\n");
462 cx_write(MO_GP0_IO, 0x00001220);
465 dprintk(1, "LNB SEC Voltage=18\n");
466 cx_write(MO_GP0_IO, 0x00001222);
468 case SEC_VOLTAGE_OFF:
469 dprintk(1, "LNB Voltage OFF\n");
470 cx_write(MO_GP0_IO, 0x00001230);
474 if (core->prev_set_voltage)
475 return core->prev_set_voltage(fe, voltage);
479 static const struct cx24123_config geniatech_dvbs_config = {
480 .demod_address = 0x55,
481 .set_ts_params = cx24123_set_ts_param,
484 static const struct cx24123_config hauppauge_novas_config = {
485 .demod_address = 0x55,
486 .set_ts_params = cx24123_set_ts_param,
489 static const struct cx24123_config kworld_dvbs_100_config = {
490 .demod_address = 0x15,
491 .set_ts_params = cx24123_set_ts_param,
495 static const struct s5h1409_config pinnacle_pctv_hd_800i_config = {
496 .demod_address = 0x32 >> 1,
497 .output_mode = S5H1409_PARALLEL_OUTPUT,
498 .gpio = S5H1409_GPIO_ON,
500 .inversion = S5H1409_INVERSION_OFF,
501 .status_mode = S5H1409_DEMODLOCKING,
502 .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
505 static const struct s5h1409_config dvico_hdtv5_pci_nano_config = {
506 .demod_address = 0x32 >> 1,
507 .output_mode = S5H1409_SERIAL_OUTPUT,
508 .gpio = S5H1409_GPIO_OFF,
509 .inversion = S5H1409_INVERSION_OFF,
510 .status_mode = S5H1409_DEMODLOCKING,
511 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
514 static const struct s5h1409_config kworld_atsc_120_config = {
515 .demod_address = 0x32 >> 1,
516 .output_mode = S5H1409_SERIAL_OUTPUT,
517 .gpio = S5H1409_GPIO_OFF,
518 .inversion = S5H1409_INVERSION_OFF,
519 .status_mode = S5H1409_DEMODLOCKING,
520 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
523 static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
528 static const struct zl10353_config cx88_pinnacle_hybrid_pctv = {
529 .demod_address = (0x1e >> 1),
534 static const struct zl10353_config cx88_geniatech_x8000_mt = {
535 .demod_address = (0x1e >> 1),
537 .disable_i2c_gate_ctrl = 1,
540 static const struct s5h1411_config dvico_fusionhdtv7_config = {
541 .output_mode = S5H1411_SERIAL_OUTPUT,
542 .gpio = S5H1411_GPIO_ON,
543 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
544 .qam_if = S5H1411_IF_44000,
545 .vsb_if = S5H1411_IF_44000,
546 .inversion = S5H1411_INVERSION_OFF,
547 .status_mode = S5H1411_DEMODLOCKING
550 static const struct xc5000_config dvico_fusionhdtv7_tuner_config = {
551 .i2c_address = 0xc2 >> 1,
555 static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
557 struct dvb_frontend *fe;
558 struct videobuf_dvb_frontend *fe0 = NULL;
559 struct xc2028_ctrl ctl;
560 struct xc2028_config cfg = {
561 .i2c_adap = &dev->core->i2c_adap,
566 /* Get the first frontend */
567 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
571 if (!fe0->dvb.frontend) {
572 printk(KERN_ERR "%s/2: dvb frontend not attached. "
573 "Can't attach xc3028\n",
579 * Some xc3028 devices may be hidden by an I2C gate. This is known
580 * to happen with some s5h1409-based devices.
581 * Now that I2C gate is open, sets up xc3028 configuration
583 cx88_setup_xc3028(dev->core, &ctl);
585 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
587 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
589 dvb_frontend_detach(fe0->dvb.frontend);
590 dvb_unregister_frontend(fe0->dvb.frontend);
591 fe0->dvb.frontend = NULL;
595 printk(KERN_INFO "%s/2: xc3028 attached\n",
601 static int cx24116_set_ts_param(struct dvb_frontend *fe,
604 struct cx8802_dev *dev = fe->dvb->priv;
605 dev->ts_gen_cntrl = 0x2;
610 static int stv0900_set_ts_param(struct dvb_frontend *fe,
613 struct cx8802_dev *dev = fe->dvb->priv;
614 dev->ts_gen_cntrl = 0;
619 static int cx24116_reset_device(struct dvb_frontend *fe)
621 struct cx8802_dev *dev = fe->dvb->priv;
622 struct cx88_core *core = dev->core;
625 /* Put the cx24116 into reset */
626 cx_write(MO_SRST_IO, 0);
628 /* Take the cx24116 out of reset */
629 cx_write(MO_SRST_IO, 1);
635 static const struct cx24116_config hauppauge_hvr4000_config = {
636 .demod_address = 0x05,
637 .set_ts_params = cx24116_set_ts_param,
638 .reset_device = cx24116_reset_device,
641 static const struct cx24116_config tevii_s460_config = {
642 .demod_address = 0x55,
643 .set_ts_params = cx24116_set_ts_param,
644 .reset_device = cx24116_reset_device,
647 static const struct stv0900_config prof_7301_stv0900_config = {
648 .demod_address = 0x6a,
651 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
652 .diseqc_mode = 2,/* 2/3 PWM */
653 .tun1_maddress = 0,/* 0x60 */
654 .tun1_adc = 0,/* 2 Vpp */
656 .set_ts_params = stv0900_set_ts_param,
659 static const struct stb6100_config prof_7301_stb6100_config = {
660 .tuner_address = 0x60,
661 .refclock = 27000000,
664 static const struct stv0299_config tevii_tuner_sharp_config = {
665 .demod_address = 0x68,
666 .inittab = sharp_z0194a_inittab,
671 .volt13_op0_op1 = STV0299_VOLT13_OP1,
673 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
674 .set_ts_params = cx24116_set_ts_param,
677 static const struct stv0288_config tevii_tuner_earda_config = {
678 .demod_address = 0x68,
680 .set_ts_params = cx24116_set_ts_param,
683 static int cx8802_alloc_frontends(struct cx8802_dev *dev)
685 struct cx88_core *core = dev->core;
686 struct videobuf_dvb_frontend *fe = NULL;
689 mutex_init(&dev->frontends.lock);
690 INIT_LIST_HEAD(&dev->frontends.felist);
692 if (!core->board.num_frontends)
695 printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
696 core->board.num_frontends);
697 for (i = 1; i <= core->board.num_frontends; i++) {
698 fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
700 printk(KERN_ERR "%s() failed to alloc\n", __func__);
701 videobuf_dvb_dealloc_frontends(&dev->frontends);
710 static const u8 samsung_smt_7020_inittab[] = {
762 static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
763 struct dvb_frontend_parameters *params)
765 struct cx8802_dev *dev = fe->dvb->priv;
768 struct i2c_msg msg = {
772 .len = sizeof(buf) };
774 div = params->frequency / 125;
776 buf[0] = (div >> 8) & 0x7f;
778 buf[2] = 0x84; /* 0xC4 */
781 if (params->frequency < 1500000)
784 if (fe->ops.i2c_gate_ctrl)
785 fe->ops.i2c_gate_ctrl(fe, 1);
787 if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
793 static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
794 fe_sec_tone_mode_t tone)
796 struct cx8802_dev *dev = fe->dvb->priv;
797 struct cx88_core *core = dev->core;
799 cx_set(MO_GP0_IO, 0x0800);
803 cx_set(MO_GP0_IO, 0x08);
806 cx_clear(MO_GP0_IO, 0x08);
815 static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
816 fe_sec_voltage_t voltage)
818 struct cx8802_dev *dev = fe->dvb->priv;
819 struct cx88_core *core = dev->core;
822 struct i2c_msg msg = {
826 .len = sizeof(data) };
828 cx_set(MO_GP0_IO, 0x8000);
831 case SEC_VOLTAGE_OFF:
834 data = ISL6421_EN1 | ISL6421_LLC1;
835 cx_clear(MO_GP0_IO, 0x80);
838 data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
839 cx_clear(MO_GP0_IO, 0x80);
845 return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
848 static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
849 u32 srate, u32 ratio)
854 if (srate < 1500000) {
857 } else if (srate < 3000000) {
860 } else if (srate < 7000000) {
863 } else if (srate < 14000000) {
866 } else if (srate < 30000000) {
869 } else if (srate < 45000000) {
874 stv0299_writereg(fe, 0x13, aclk);
875 stv0299_writereg(fe, 0x14, bclk);
876 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
877 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
878 stv0299_writereg(fe, 0x21, ratio & 0xf0);
884 static const struct stv0299_config samsung_stv0299_config = {
885 .demod_address = 0x68,
886 .inittab = samsung_smt_7020_inittab,
890 .lock_output = STV0299_LOCKOUTPUT_LK,
891 .volt13_op0_op1 = STV0299_VOLT13_OP1,
893 .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
896 static int dvb_register(struct cx8802_dev *dev)
898 struct cx88_core *core = dev->core;
899 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
900 int mfe_shared = 0; /* bus not shared by default */
902 if (0 != core->i2c_rc) {
903 printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
904 goto frontend_detach;
907 /* Get the first frontend */
908 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
910 goto frontend_detach;
912 /* multi-frontend gate control is undefined or defaults to fe0 */
913 dev->frontends.gate = 0;
915 /* Sets the gate control callback to be used by i2c command calls */
916 core->gate_ctrl = cx88_dvb_gate_ctrl;
918 /* init frontend(s) */
919 switch (core->boardnr) {
920 case CX88_BOARD_HAUPPAUGE_DVB_T1:
921 fe0->dvb.frontend = dvb_attach(cx22702_attach,
922 &connexant_refboard_config,
924 if (fe0->dvb.frontend != NULL) {
925 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
926 0x61, &core->i2c_adap,
927 DVB_PLL_THOMSON_DTT759X))
928 goto frontend_detach;
931 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
932 case CX88_BOARD_CONEXANT_DVB_T1:
933 case CX88_BOARD_KWORLD_DVB_T_CX22702:
934 case CX88_BOARD_WINFAST_DTV1000:
935 fe0->dvb.frontend = dvb_attach(cx22702_attach,
936 &connexant_refboard_config,
938 if (fe0->dvb.frontend != NULL) {
939 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
940 0x60, &core->i2c_adap,
941 DVB_PLL_THOMSON_DTT7579))
942 goto frontend_detach;
945 case CX88_BOARD_WINFAST_DTV2000H:
946 case CX88_BOARD_WINFAST_DTV2000H_J:
947 case CX88_BOARD_HAUPPAUGE_HVR1100:
948 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
949 case CX88_BOARD_HAUPPAUGE_HVR1300:
950 fe0->dvb.frontend = dvb_attach(cx22702_attach,
951 &hauppauge_hvr_config,
953 if (fe0->dvb.frontend != NULL) {
954 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
955 &core->i2c_adap, 0x61,
956 TUNER_PHILIPS_FMD1216ME_MK3))
957 goto frontend_detach;
960 case CX88_BOARD_HAUPPAUGE_HVR3000:
963 dev->frontends.gate = 2;
965 fe0->dvb.frontend = dvb_attach(cx24123_attach,
966 &hauppauge_novas_config,
967 &dev->core->i2c_adap);
968 if (fe0->dvb.frontend) {
969 if (!dvb_attach(isl6421_attach,
971 &dev->core->i2c_adap,
972 0x08, ISL6421_DCL, 0x00))
973 goto frontend_detach;
976 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
978 goto frontend_detach;
980 fe1->dvb.frontend = dvb_attach(cx22702_attach,
981 &hauppauge_hvr_config,
982 &dev->core->i2c_adap);
983 if (fe1->dvb.frontend) {
984 fe1->dvb.frontend->id = 1;
985 if (!dvb_attach(simple_tuner_attach,
987 &dev->core->i2c_adap,
988 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
989 goto frontend_detach;
992 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
993 fe0->dvb.frontend = dvb_attach(mt352_attach,
996 if (fe0->dvb.frontend != NULL) {
997 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
998 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
999 goto frontend_detach;
1002 /* ZL10353 replaces MT352 on later cards */
1003 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1004 &dvico_fusionhdtv_plus_v1_1,
1006 if (fe0->dvb.frontend != NULL) {
1007 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1008 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1009 goto frontend_detach;
1012 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1013 /* The tin box says DEE1601, but it seems to be DTT7579
1014 * compatible, with a slightly different MT352 AGC gain. */
1015 fe0->dvb.frontend = dvb_attach(mt352_attach,
1016 &dvico_fusionhdtv_dual,
1018 if (fe0->dvb.frontend != NULL) {
1019 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1020 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1021 goto frontend_detach;
1024 /* ZL10353 replaces MT352 on later cards */
1025 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1026 &dvico_fusionhdtv_plus_v1_1,
1028 if (fe0->dvb.frontend != NULL) {
1029 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1030 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1031 goto frontend_detach;
1034 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
1035 fe0->dvb.frontend = dvb_attach(mt352_attach,
1038 if (fe0->dvb.frontend != NULL) {
1039 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1040 0x61, NULL, DVB_PLL_LG_Z201))
1041 goto frontend_detach;
1044 case CX88_BOARD_KWORLD_DVB_T:
1045 case CX88_BOARD_DNTV_LIVE_DVB_T:
1046 case CX88_BOARD_ADSTECH_DVB_T_PCI:
1047 fe0->dvb.frontend = dvb_attach(mt352_attach,
1048 &dntv_live_dvbt_config,
1050 if (fe0->dvb.frontend != NULL) {
1051 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1052 0x61, NULL, DVB_PLL_UNKNOWN_1))
1053 goto frontend_detach;
1056 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
1057 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
1058 /* MT352 is on a secondary I2C bus made from some GPIO lines */
1059 fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
1060 &dev->vp3054->adap);
1061 if (fe0->dvb.frontend != NULL) {
1062 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1063 &core->i2c_adap, 0x61,
1064 TUNER_PHILIPS_FMD1216ME_MK3))
1065 goto frontend_detach;
1068 printk(KERN_ERR "%s/2: built without vp3054 support\n",
1072 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
1073 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1074 &dvico_fusionhdtv_hybrid,
1076 if (fe0->dvb.frontend != NULL) {
1077 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1078 &core->i2c_adap, 0x61,
1079 TUNER_THOMSON_FE6600))
1080 goto frontend_detach;
1083 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
1084 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1085 &dvico_fusionhdtv_xc3028,
1087 if (fe0->dvb.frontend == NULL)
1088 fe0->dvb.frontend = dvb_attach(mt352_attach,
1089 &dvico_fusionhdtv_mt352_xc3028,
1092 * On this board, the demod provides the I2C bus pullup.
1093 * We must not permit gate_ctrl to be performed, or
1094 * the xc3028 cannot communicate on the bus.
1096 if (fe0->dvb.frontend)
1097 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1098 if (attach_xc3028(0x61, dev) < 0)
1099 goto frontend_detach;
1101 case CX88_BOARD_PCHDTV_HD3000:
1102 fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
1104 if (fe0->dvb.frontend != NULL) {
1105 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1106 &core->i2c_adap, 0x61,
1107 TUNER_THOMSON_DTT761X))
1108 goto frontend_detach;
1111 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
1112 dev->ts_gen_cntrl = 0x08;
1114 /* Do a hardware reset of chip before using it. */
1115 cx_clear(MO_GP0_IO, 1);
1117 cx_set(MO_GP0_IO, 1);
1120 /* Select RF connector callback */
1121 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
1122 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1125 if (fe0->dvb.frontend != NULL) {
1126 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1127 &core->i2c_adap, 0x61,
1128 TUNER_MICROTUNE_4042FI5))
1129 goto frontend_detach;
1132 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
1133 dev->ts_gen_cntrl = 0x08;
1135 /* Do a hardware reset of chip before using it. */
1136 cx_clear(MO_GP0_IO, 1);
1138 cx_set(MO_GP0_IO, 9);
1140 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1143 if (fe0->dvb.frontend != NULL) {
1144 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1145 &core->i2c_adap, 0x61,
1146 TUNER_THOMSON_DTT761X))
1147 goto frontend_detach;
1150 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
1151 dev->ts_gen_cntrl = 0x08;
1153 /* Do a hardware reset of chip before using it. */
1154 cx_clear(MO_GP0_IO, 1);
1156 cx_set(MO_GP0_IO, 1);
1158 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1161 if (fe0->dvb.frontend != NULL) {
1162 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1163 &core->i2c_adap, 0x61,
1164 TUNER_LG_TDVS_H06XF))
1165 goto frontend_detach;
1166 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1167 &core->i2c_adap, 0x43))
1168 goto frontend_detach;
1171 case CX88_BOARD_PCHDTV_HD5500:
1172 dev->ts_gen_cntrl = 0x08;
1174 /* Do a hardware reset of chip before using it. */
1175 cx_clear(MO_GP0_IO, 1);
1177 cx_set(MO_GP0_IO, 1);
1179 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1182 if (fe0->dvb.frontend != NULL) {
1183 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1184 &core->i2c_adap, 0x61,
1185 TUNER_LG_TDVS_H06XF))
1186 goto frontend_detach;
1187 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1188 &core->i2c_adap, 0x43))
1189 goto frontend_detach;
1192 case CX88_BOARD_ATI_HDTVWONDER:
1193 fe0->dvb.frontend = dvb_attach(nxt200x_attach,
1196 if (fe0->dvb.frontend != NULL) {
1197 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1198 &core->i2c_adap, 0x61,
1199 TUNER_PHILIPS_TUV1236D))
1200 goto frontend_detach;
1203 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
1204 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
1205 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1206 &hauppauge_novas_config,
1208 if (fe0->dvb.frontend) {
1209 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
1210 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
1211 goto frontend_detach;
1214 case CX88_BOARD_KWORLD_DVBS_100:
1215 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1216 &kworld_dvbs_100_config,
1218 if (fe0->dvb.frontend) {
1219 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1220 fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
1223 case CX88_BOARD_GENIATECH_DVBS:
1224 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1225 &geniatech_dvbs_config,
1227 if (fe0->dvb.frontend) {
1228 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1229 fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
1232 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
1233 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1234 &pinnacle_pctv_hd_800i_config,
1236 if (fe0->dvb.frontend != NULL) {
1237 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1239 &pinnacle_pctv_hd_800i_tuner_config))
1240 goto frontend_detach;
1243 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
1244 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1245 &dvico_hdtv5_pci_nano_config,
1247 if (fe0->dvb.frontend != NULL) {
1248 struct dvb_frontend *fe;
1249 struct xc2028_config cfg = {
1250 .i2c_adap = &core->i2c_adap,
1253 static struct xc2028_ctrl ctl = {
1254 .fname = XC2028_DEFAULT_FIRMWARE,
1256 .scode_table = XC3028_FE_OREN538,
1259 fe = dvb_attach(xc2028_attach,
1260 fe0->dvb.frontend, &cfg);
1261 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1262 fe->ops.tuner_ops.set_config(fe, &ctl);
1265 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
1266 case CX88_BOARD_WINFAST_DTV1800H:
1267 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1268 &cx88_pinnacle_hybrid_pctv,
1270 if (fe0->dvb.frontend) {
1271 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1272 if (attach_xc3028(0x61, dev) < 0)
1273 goto frontend_detach;
1276 case CX88_BOARD_GENIATECH_X8000_MT:
1277 dev->ts_gen_cntrl = 0x00;
1279 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1280 &cx88_geniatech_x8000_mt,
1282 if (attach_xc3028(0x61, dev) < 0)
1283 goto frontend_detach;
1285 case CX88_BOARD_KWORLD_ATSC_120:
1286 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1287 &kworld_atsc_120_config,
1289 if (attach_xc3028(0x61, dev) < 0)
1290 goto frontend_detach;
1292 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
1293 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1294 &dvico_fusionhdtv7_config,
1296 if (fe0->dvb.frontend != NULL) {
1297 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1299 &dvico_fusionhdtv7_tuner_config))
1300 goto frontend_detach;
1303 case CX88_BOARD_HAUPPAUGE_HVR4000:
1304 /* MFE frontend 1 */
1306 dev->frontends.gate = 2;
1308 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1309 &hauppauge_hvr4000_config,
1310 &dev->core->i2c_adap);
1311 if (fe0->dvb.frontend) {
1312 if (!dvb_attach(isl6421_attach,
1314 &dev->core->i2c_adap,
1315 0x08, ISL6421_DCL, 0x00))
1316 goto frontend_detach;
1318 /* MFE frontend 2 */
1319 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1321 goto frontend_detach;
1323 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1324 &hauppauge_hvr_config,
1325 &dev->core->i2c_adap);
1326 if (fe1->dvb.frontend) {
1327 fe1->dvb.frontend->id = 1;
1328 if (!dvb_attach(simple_tuner_attach,
1330 &dev->core->i2c_adap,
1331 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1332 goto frontend_detach;
1335 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
1336 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1337 &hauppauge_hvr4000_config,
1338 &dev->core->i2c_adap);
1339 if (fe0->dvb.frontend) {
1340 if (!dvb_attach(isl6421_attach,
1342 &dev->core->i2c_adap,
1343 0x08, ISL6421_DCL, 0x00))
1344 goto frontend_detach;
1347 case CX88_BOARD_PROF_6200:
1348 case CX88_BOARD_TBS_8910:
1349 case CX88_BOARD_TEVII_S420:
1350 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1351 &tevii_tuner_sharp_config,
1353 if (fe0->dvb.frontend != NULL) {
1354 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
1355 &core->i2c_adap, DVB_PLL_OPERA1))
1356 goto frontend_detach;
1357 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1358 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1361 fe0->dvb.frontend = dvb_attach(stv0288_attach,
1362 &tevii_tuner_earda_config,
1364 if (fe0->dvb.frontend != NULL) {
1365 if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
1367 goto frontend_detach;
1368 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1369 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1373 case CX88_BOARD_TEVII_S460:
1374 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1377 if (fe0->dvb.frontend != NULL)
1378 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1380 case CX88_BOARD_OMICOM_SS4_PCI:
1381 case CX88_BOARD_TBS_8920:
1382 case CX88_BOARD_PROF_7300:
1383 case CX88_BOARD_SATTRADE_ST4200:
1384 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1385 &hauppauge_hvr4000_config,
1387 if (fe0->dvb.frontend != NULL)
1388 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1390 case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
1391 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1392 &cx88_terratec_cinergy_ht_pci_mkii_config,
1394 if (fe0->dvb.frontend) {
1395 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1396 if (attach_xc3028(0x61, dev) < 0)
1397 goto frontend_detach;
1400 case CX88_BOARD_PROF_7301:{
1401 struct dvb_tuner_ops *tuner_ops = NULL;
1403 fe0->dvb.frontend = dvb_attach(stv0900_attach,
1404 &prof_7301_stv0900_config,
1405 &core->i2c_adap, 0);
1406 if (fe0->dvb.frontend != NULL) {
1407 if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
1408 &prof_7301_stb6100_config,
1410 goto frontend_detach;
1412 tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
1413 tuner_ops->set_frequency = stb6100_set_freq;
1414 tuner_ops->get_frequency = stb6100_get_freq;
1415 tuner_ops->set_bandwidth = stb6100_set_bandw;
1416 tuner_ops->get_bandwidth = stb6100_get_bandw;
1418 core->prev_set_voltage =
1419 fe0->dvb.frontend->ops.set_voltage;
1420 fe0->dvb.frontend->ops.set_voltage =
1421 tevii_dvbs_set_voltage;
1425 case CX88_BOARD_SAMSUNG_SMT_7020:
1426 dev->ts_gen_cntrl = 0x08;
1428 cx_set(MO_GP0_IO, 0x0101);
1430 cx_clear(MO_GP0_IO, 0x01);
1432 cx_set(MO_GP0_IO, 0x01);
1435 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1436 &samsung_stv0299_config,
1437 &dev->core->i2c_adap);
1438 if (fe0->dvb.frontend) {
1439 fe0->dvb.frontend->ops.tuner_ops.set_params =
1440 samsung_smt_7020_tuner_set_params;
1441 fe0->dvb.frontend->tuner_priv =
1442 &dev->core->i2c_adap;
1443 fe0->dvb.frontend->ops.set_voltage =
1444 samsung_smt_7020_set_voltage;
1445 fe0->dvb.frontend->ops.set_tone =
1446 samsung_smt_7020_set_tone;
1450 case CX88_BOARD_TWINHAN_VP1027_DVBS:
1451 dev->ts_gen_cntrl = 0x00;
1452 fe0->dvb.frontend = dvb_attach(mb86a16_attach,
1455 if (fe0->dvb.frontend) {
1456 core->prev_set_voltage =
1457 fe0->dvb.frontend->ops.set_voltage;
1458 fe0->dvb.frontend->ops.set_voltage =
1464 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1469 if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
1471 "%s/2: frontend initialization failed\n",
1473 goto frontend_detach;
1475 /* define general-purpose callback pointer */
1476 fe0->dvb.frontend->callback = cx88_tuner_callback;
1478 /* Ensure all frontends negotiate bus access */
1479 fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1481 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1483 /* Put the analog decoder in standby to keep it quiet */
1484 call_all(core, core, s_power, 0);
1486 /* register everything */
1487 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1488 &dev->pci->dev, adapter_nr, mfe_shared, NULL);
1491 core->gate_ctrl = NULL;
1492 videobuf_dvb_dealloc_frontends(&dev->frontends);
1496 /* ----------------------------------------------------------- */
1498 /* CX8802 MPEG -> mini driver - We have been given the hardware */
1499 static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
1501 struct cx88_core *core = drv->core;
1503 dprintk( 1, "%s\n", __func__);
1505 switch (core->boardnr) {
1506 case CX88_BOARD_HAUPPAUGE_HVR1300:
1507 /* We arrive here with either the cx23416 or the cx22702
1508 * on the bus. Take the bus from the cx23416 and enable the
1511 /* Toggle reset on cx22702 leaving i2c active */
1512 cx_set(MO_GP0_IO, 0x00000080);
1514 cx_clear(MO_GP0_IO, 0x00000080);
1516 cx_set(MO_GP0_IO, 0x00000080);
1518 /* enable the cx22702 pins */
1519 cx_clear(MO_GP0_IO, 0x00000004);
1523 case CX88_BOARD_HAUPPAUGE_HVR3000:
1524 case CX88_BOARD_HAUPPAUGE_HVR4000:
1525 /* Toggle reset on cx22702 leaving i2c active */
1526 cx_set(MO_GP0_IO, 0x00000080);
1528 cx_clear(MO_GP0_IO, 0x00000080);
1530 cx_set(MO_GP0_IO, 0x00000080);
1532 switch (core->dvbdev->frontends.active_fe_id) {
1533 case 1: /* DVB-S/S2 Enabled */
1534 /* tri-state the cx22702 pins */
1535 cx_set(MO_GP0_IO, 0x00000004);
1536 /* Take the cx24116/cx24123 out of reset */
1537 cx_write(MO_SRST_IO, 1);
1538 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1540 case 2: /* DVB-T Enabled */
1541 /* Put the cx24116/cx24123 into reset */
1542 cx_write(MO_SRST_IO, 0);
1543 /* enable the cx22702 pins */
1544 cx_clear(MO_GP0_IO, 0x00000004);
1545 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1557 /* CX8802 MPEG -> mini driver - We no longer have the hardware */
1558 static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
1560 struct cx88_core *core = drv->core;
1562 dprintk( 1, "%s\n", __func__);
1564 switch (core->boardnr) {
1565 case CX88_BOARD_HAUPPAUGE_HVR1300:
1566 /* Do Nothing, leave the cx22702 on the bus. */
1568 case CX88_BOARD_HAUPPAUGE_HVR3000:
1569 case CX88_BOARD_HAUPPAUGE_HVR4000:
1577 static int cx8802_dvb_probe(struct cx8802_driver *drv)
1579 struct cx88_core *core = drv->core;
1580 struct cx8802_dev *dev = drv->core->dvbdev;
1582 struct videobuf_dvb_frontend *fe;
1585 dprintk( 1, "%s\n", __func__);
1586 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1593 if (!(core->board.mpeg & CX88_MPEG_DVB))
1596 /* If vp3054 isn't enabled, a stub will just return 0 */
1597 err = vp3054_i2c_probe(dev);
1602 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1603 dev->ts_gen_cntrl = 0x0c;
1605 err = cx8802_alloc_frontends(dev);
1610 for (i = 1; i <= core->board.num_frontends; i++) {
1611 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
1613 printk(KERN_ERR "%s() failed to get frontend(%d)\n",
1617 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
1618 &dev->pci->dev, &dev->slock,
1619 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1621 sizeof(struct cx88_buffer),
1623 /* init struct videobuf_dvb */
1624 fe->dvb.name = dev->core->name;
1627 err = dvb_register(dev);
1629 /* frontends/adapter de-allocated in dvb_register */
1630 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
1634 videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends);
1639 static int cx8802_dvb_remove(struct cx8802_driver *drv)
1641 struct cx88_core *core = drv->core;
1642 struct cx8802_dev *dev = drv->core->dvbdev;
1644 dprintk( 1, "%s\n", __func__);
1646 videobuf_dvb_unregister_bus(&dev->frontends);
1648 vp3054_i2c_remove(dev);
1650 core->gate_ctrl = NULL;
1655 static struct cx8802_driver cx8802_dvb_driver = {
1656 .type_id = CX88_MPEG_DVB,
1657 .hw_access = CX8802_DRVCTL_SHARED,
1658 .probe = cx8802_dvb_probe,
1659 .remove = cx8802_dvb_remove,
1660 .advise_acquire = cx8802_dvb_advise_acquire,
1661 .advise_release = cx8802_dvb_advise_release,
1664 static int __init dvb_init(void)
1666 printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n",
1667 (CX88_VERSION_CODE >> 16) & 0xff,
1668 (CX88_VERSION_CODE >> 8) & 0xff,
1669 CX88_VERSION_CODE & 0xff);
1671 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
1672 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1674 return cx8802_register_driver(&cx8802_dvb_driver);
1677 static void __exit dvb_fini(void)
1679 cx8802_unregister_driver(&cx8802_dvb_driver);
1682 module_init(dvb_init);
1683 module_exit(dvb_fini);
1688 * compile-command: "make DVB=1"