[media] cx88: added XC4000 tuner callback and DVB attach functions
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / video / cx88 / cx88-dvb.c
blobf0fbff499f0135d2762c7822b06ea625e4263845
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 "xc4000.h"
45 #include "xc5000.h"
46 #include "nxt200x.h"
47 #include "cx24123.h"
48 #include "isl6421.h"
49 #include "tuner-simple.h"
50 #include "tda9887.h"
51 #include "s5h1411.h"
52 #include "stv0299.h"
53 #include "z0194a.h"
54 #include "stv0288.h"
55 #include "stb6000.h"
56 #include "cx24116.h"
57 #include "stv0900.h"
58 #include "stb6100.h"
59 #include "stb6100_proc.h"
60 #include "mb86a16.h"
61 #include "ds3000.h"
63 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
64 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
65 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
66 MODULE_LICENSE("GPL");
68 static unsigned int debug;
69 module_param(debug, int, 0644);
70 MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
72 static unsigned int dvb_buf_tscnt = 32;
73 module_param(dvb_buf_tscnt, int, 0644);
74 MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]");
76 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
78 #define dprintk(level,fmt, arg...) if (debug >= level) \
79 printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
81 /* ------------------------------------------------------------------ */
83 static int dvb_buf_setup(struct videobuf_queue *q,
84 unsigned int *count, unsigned int *size)
86 struct cx8802_dev *dev = q->priv_data;
88 dev->ts_packet_size = 188 * 4;
89 dev->ts_packet_count = dvb_buf_tscnt;
91 *size = dev->ts_packet_size * dev->ts_packet_count;
92 *count = dvb_buf_tscnt;
93 return 0;
96 static int dvb_buf_prepare(struct videobuf_queue *q,
97 struct videobuf_buffer *vb, enum v4l2_field field)
99 struct cx8802_dev *dev = q->priv_data;
100 return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
103 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
105 struct cx8802_dev *dev = q->priv_data;
106 cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
109 static void dvb_buf_release(struct videobuf_queue *q,
110 struct videobuf_buffer *vb)
112 cx88_free_buffer(q, (struct cx88_buffer*)vb);
115 static const struct videobuf_queue_ops dvb_qops = {
116 .buf_setup = dvb_buf_setup,
117 .buf_prepare = dvb_buf_prepare,
118 .buf_queue = dvb_buf_queue,
119 .buf_release = dvb_buf_release,
122 /* ------------------------------------------------------------------ */
124 static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
126 struct cx8802_dev *dev= fe->dvb->priv;
127 struct cx8802_driver *drv = NULL;
128 int ret = 0;
129 int fe_id;
131 fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
132 if (!fe_id) {
133 printk(KERN_ERR "%s() No frontend found\n", __func__);
134 return -EINVAL;
137 mutex_lock(&dev->core->lock);
138 drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
139 if (drv) {
140 if (acquire){
141 dev->frontends.active_fe_id = fe_id;
142 ret = drv->request_acquire(drv);
143 } else {
144 ret = drv->request_release(drv);
145 dev->frontends.active_fe_id = 0;
148 mutex_unlock(&dev->core->lock);
150 return ret;
153 static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open)
155 struct videobuf_dvb_frontends *f;
156 struct videobuf_dvb_frontend *fe;
158 if (!core->dvbdev)
159 return;
161 f = &core->dvbdev->frontends;
163 if (!f)
164 return;
166 if (f->gate <= 1) /* undefined or fe0 */
167 fe = videobuf_dvb_get_frontend(f, 1);
168 else
169 fe = videobuf_dvb_get_frontend(f, f->gate);
171 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
172 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
175 /* ------------------------------------------------------------------ */
177 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
179 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
180 static const u8 reset [] = { RESET, 0x80 };
181 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
182 static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
183 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
184 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
186 mt352_write(fe, clock_config, sizeof(clock_config));
187 udelay(200);
188 mt352_write(fe, reset, sizeof(reset));
189 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
191 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
192 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
193 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
194 return 0;
197 static int dvico_dual_demod_init(struct dvb_frontend *fe)
199 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
200 static const u8 reset [] = { RESET, 0x80 };
201 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
202 static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
203 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
204 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
206 mt352_write(fe, clock_config, sizeof(clock_config));
207 udelay(200);
208 mt352_write(fe, reset, sizeof(reset));
209 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
211 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
212 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
213 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
215 return 0;
218 static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
220 static const u8 clock_config [] = { 0x89, 0x38, 0x39 };
221 static const u8 reset [] = { 0x50, 0x80 };
222 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
223 static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
224 0x00, 0xFF, 0x00, 0x40, 0x40 };
225 static const u8 dntv_extra[] = { 0xB5, 0x7A };
226 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
228 mt352_write(fe, clock_config, sizeof(clock_config));
229 udelay(2000);
230 mt352_write(fe, reset, sizeof(reset));
231 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
233 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
234 udelay(2000);
235 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
236 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
238 return 0;
241 static const struct mt352_config dvico_fusionhdtv = {
242 .demod_address = 0x0f,
243 .demod_init = dvico_fusionhdtv_demod_init,
246 static const struct mt352_config dntv_live_dvbt_config = {
247 .demod_address = 0x0f,
248 .demod_init = dntv_live_dvbt_demod_init,
251 static const struct mt352_config dvico_fusionhdtv_dual = {
252 .demod_address = 0x0f,
253 .demod_init = dvico_dual_demod_init,
256 static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
257 .demod_address = (0x1e >> 1),
258 .no_tuner = 1,
259 .if2 = 45600,
262 static struct mb86a16_config twinhan_vp1027 = {
263 .demod_address = 0x08,
266 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
267 static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
269 static const u8 clock_config [] = { 0x89, 0x38, 0x38 };
270 static const u8 reset [] = { 0x50, 0x80 };
271 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
272 static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
273 0x00, 0xFF, 0x00, 0x40, 0x40 };
274 static const u8 dntv_extra[] = { 0xB5, 0x7A };
275 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
277 mt352_write(fe, clock_config, sizeof(clock_config));
278 udelay(2000);
279 mt352_write(fe, reset, sizeof(reset));
280 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
282 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
283 udelay(2000);
284 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
285 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
287 return 0;
290 static const struct mt352_config dntv_live_dvbt_pro_config = {
291 .demod_address = 0x0f,
292 .no_tuner = 1,
293 .demod_init = dntv_live_dvbt_pro_demod_init,
295 #endif
297 static const struct zl10353_config dvico_fusionhdtv_hybrid = {
298 .demod_address = 0x0f,
299 .no_tuner = 1,
302 static const struct zl10353_config dvico_fusionhdtv_xc3028 = {
303 .demod_address = 0x0f,
304 .if2 = 45600,
305 .no_tuner = 1,
308 static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
309 .demod_address = 0x0f,
310 .if2 = 4560,
311 .no_tuner = 1,
312 .demod_init = dvico_fusionhdtv_demod_init,
315 static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
316 .demod_address = 0x0f,
319 static const struct cx22702_config connexant_refboard_config = {
320 .demod_address = 0x43,
321 .output_mode = CX22702_SERIAL_OUTPUT,
324 static const struct cx22702_config hauppauge_hvr_config = {
325 .demod_address = 0x63,
326 .output_mode = CX22702_SERIAL_OUTPUT,
329 static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
331 struct cx8802_dev *dev= fe->dvb->priv;
332 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
333 return 0;
336 static const struct or51132_config pchdtv_hd3000 = {
337 .demod_address = 0x15,
338 .set_ts_params = or51132_set_ts_param,
341 static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
343 struct cx8802_dev *dev= fe->dvb->priv;
344 struct cx88_core *core = dev->core;
346 dprintk(1, "%s: index = %d\n", __func__, index);
347 if (index == 0)
348 cx_clear(MO_GP0_IO, 8);
349 else
350 cx_set(MO_GP0_IO, 8);
351 return 0;
354 static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
356 struct cx8802_dev *dev= fe->dvb->priv;
357 if (is_punctured)
358 dev->ts_gen_cntrl |= 0x04;
359 else
360 dev->ts_gen_cntrl &= ~0x04;
361 return 0;
364 static struct lgdt330x_config fusionhdtv_3_gold = {
365 .demod_address = 0x0e,
366 .demod_chip = LGDT3302,
367 .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
368 .set_ts_params = lgdt330x_set_ts_param,
371 static const struct lgdt330x_config fusionhdtv_5_gold = {
372 .demod_address = 0x0e,
373 .demod_chip = LGDT3303,
374 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
375 .set_ts_params = lgdt330x_set_ts_param,
378 static const struct lgdt330x_config pchdtv_hd5500 = {
379 .demod_address = 0x59,
380 .demod_chip = LGDT3303,
381 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
382 .set_ts_params = lgdt330x_set_ts_param,
385 static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
387 struct cx8802_dev *dev= fe->dvb->priv;
388 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
389 return 0;
392 static const struct nxt200x_config ati_hdtvwonder = {
393 .demod_address = 0x0a,
394 .set_ts_params = nxt200x_set_ts_param,
397 static int cx24123_set_ts_param(struct dvb_frontend* fe,
398 int is_punctured)
400 struct cx8802_dev *dev= fe->dvb->priv;
401 dev->ts_gen_cntrl = 0x02;
402 return 0;
405 static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
406 fe_sec_voltage_t voltage)
408 struct cx8802_dev *dev= fe->dvb->priv;
409 struct cx88_core *core = dev->core;
411 if (voltage == SEC_VOLTAGE_OFF)
412 cx_write(MO_GP0_IO, 0x000006fb);
413 else
414 cx_write(MO_GP0_IO, 0x000006f9);
416 if (core->prev_set_voltage)
417 return core->prev_set_voltage(fe, voltage);
418 return 0;
421 static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
422 fe_sec_voltage_t voltage)
424 struct cx8802_dev *dev= fe->dvb->priv;
425 struct cx88_core *core = dev->core;
427 if (voltage == SEC_VOLTAGE_OFF) {
428 dprintk(1,"LNB Voltage OFF\n");
429 cx_write(MO_GP0_IO, 0x0000efff);
432 if (core->prev_set_voltage)
433 return core->prev_set_voltage(fe, voltage);
434 return 0;
437 static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
438 fe_sec_voltage_t voltage)
440 struct cx8802_dev *dev= fe->dvb->priv;
441 struct cx88_core *core = dev->core;
443 cx_set(MO_GP0_IO, 0x6040);
444 switch (voltage) {
445 case SEC_VOLTAGE_13:
446 cx_clear(MO_GP0_IO, 0x20);
447 break;
448 case SEC_VOLTAGE_18:
449 cx_set(MO_GP0_IO, 0x20);
450 break;
451 case SEC_VOLTAGE_OFF:
452 cx_clear(MO_GP0_IO, 0x20);
453 break;
456 if (core->prev_set_voltage)
457 return core->prev_set_voltage(fe, voltage);
458 return 0;
461 static int vp1027_set_voltage(struct dvb_frontend *fe,
462 fe_sec_voltage_t voltage)
464 struct cx8802_dev *dev = fe->dvb->priv;
465 struct cx88_core *core = dev->core;
467 switch (voltage) {
468 case SEC_VOLTAGE_13:
469 dprintk(1, "LNB SEC Voltage=13\n");
470 cx_write(MO_GP0_IO, 0x00001220);
471 break;
472 case SEC_VOLTAGE_18:
473 dprintk(1, "LNB SEC Voltage=18\n");
474 cx_write(MO_GP0_IO, 0x00001222);
475 break;
476 case SEC_VOLTAGE_OFF:
477 dprintk(1, "LNB Voltage OFF\n");
478 cx_write(MO_GP0_IO, 0x00001230);
479 break;
482 if (core->prev_set_voltage)
483 return core->prev_set_voltage(fe, voltage);
484 return 0;
487 static const struct cx24123_config geniatech_dvbs_config = {
488 .demod_address = 0x55,
489 .set_ts_params = cx24123_set_ts_param,
492 static const struct cx24123_config hauppauge_novas_config = {
493 .demod_address = 0x55,
494 .set_ts_params = cx24123_set_ts_param,
497 static const struct cx24123_config kworld_dvbs_100_config = {
498 .demod_address = 0x15,
499 .set_ts_params = cx24123_set_ts_param,
500 .lnb_polarity = 1,
503 static const struct s5h1409_config pinnacle_pctv_hd_800i_config = {
504 .demod_address = 0x32 >> 1,
505 .output_mode = S5H1409_PARALLEL_OUTPUT,
506 .gpio = S5H1409_GPIO_ON,
507 .qam_if = 44000,
508 .inversion = S5H1409_INVERSION_OFF,
509 .status_mode = S5H1409_DEMODLOCKING,
510 .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
513 static const struct s5h1409_config dvico_hdtv5_pci_nano_config = {
514 .demod_address = 0x32 >> 1,
515 .output_mode = S5H1409_SERIAL_OUTPUT,
516 .gpio = S5H1409_GPIO_OFF,
517 .inversion = S5H1409_INVERSION_OFF,
518 .status_mode = S5H1409_DEMODLOCKING,
519 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
522 static const struct s5h1409_config kworld_atsc_120_config = {
523 .demod_address = 0x32 >> 1,
524 .output_mode = S5H1409_SERIAL_OUTPUT,
525 .gpio = S5H1409_GPIO_OFF,
526 .inversion = S5H1409_INVERSION_OFF,
527 .status_mode = S5H1409_DEMODLOCKING,
528 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
531 static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
532 .i2c_address = 0x64,
533 .if_khz = 5380,
536 static const struct zl10353_config cx88_pinnacle_hybrid_pctv = {
537 .demod_address = (0x1e >> 1),
538 .no_tuner = 1,
539 .if2 = 45600,
542 static const struct zl10353_config cx88_geniatech_x8000_mt = {
543 .demod_address = (0x1e >> 1),
544 .no_tuner = 1,
545 .disable_i2c_gate_ctrl = 1,
548 static const struct s5h1411_config dvico_fusionhdtv7_config = {
549 .output_mode = S5H1411_SERIAL_OUTPUT,
550 .gpio = S5H1411_GPIO_ON,
551 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
552 .qam_if = S5H1411_IF_44000,
553 .vsb_if = S5H1411_IF_44000,
554 .inversion = S5H1411_INVERSION_OFF,
555 .status_mode = S5H1411_DEMODLOCKING
558 static const struct xc5000_config dvico_fusionhdtv7_tuner_config = {
559 .i2c_address = 0xc2 >> 1,
560 .if_khz = 5380,
563 static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
565 struct dvb_frontend *fe;
566 struct videobuf_dvb_frontend *fe0 = NULL;
567 struct xc2028_ctrl ctl;
568 struct xc2028_config cfg = {
569 .i2c_adap = &dev->core->i2c_adap,
570 .i2c_addr = addr,
571 .ctrl = &ctl,
574 /* Get the first frontend */
575 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
576 if (!fe0)
577 return -EINVAL;
579 if (!fe0->dvb.frontend) {
580 printk(KERN_ERR "%s/2: dvb frontend not attached. "
581 "Can't attach xc3028\n",
582 dev->core->name);
583 return -EINVAL;
587 * Some xc3028 devices may be hidden by an I2C gate. This is known
588 * to happen with some s5h1409-based devices.
589 * Now that I2C gate is open, sets up xc3028 configuration
591 cx88_setup_xc3028(dev->core, &ctl);
593 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
594 if (!fe) {
595 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
596 dev->core->name);
597 dvb_frontend_detach(fe0->dvb.frontend);
598 dvb_unregister_frontend(fe0->dvb.frontend);
599 fe0->dvb.frontend = NULL;
600 return -EINVAL;
603 printk(KERN_INFO "%s/2: xc3028 attached\n",
604 dev->core->name);
606 return 0;
609 static int attach_xc4000(struct cx8802_dev *dev, struct xc4000_config *cfg)
611 struct dvb_frontend *fe;
612 struct videobuf_dvb_frontend *fe0 = NULL;
614 /* Get the first frontend */
615 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
616 if (!fe0)
617 return -EINVAL;
619 if (!fe0->dvb.frontend) {
620 printk(KERN_ERR "%s/2: dvb frontend not attached. "
621 "Can't attach xc4000\n",
622 dev->core->name);
623 return -EINVAL;
626 fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->core->i2c_adap,
627 cfg);
628 if (!fe) {
629 printk(KERN_ERR "%s/2: xc4000 attach failed\n",
630 dev->core->name);
631 dvb_frontend_detach(fe0->dvb.frontend);
632 dvb_unregister_frontend(fe0->dvb.frontend);
633 fe0->dvb.frontend = NULL;
634 return -EINVAL;
637 printk(KERN_INFO "%s/2: xc4000 attached\n", dev->core->name);
639 return 0;
642 static int cx24116_set_ts_param(struct dvb_frontend *fe,
643 int is_punctured)
645 struct cx8802_dev *dev = fe->dvb->priv;
646 dev->ts_gen_cntrl = 0x2;
648 return 0;
651 static int stv0900_set_ts_param(struct dvb_frontend *fe,
652 int is_punctured)
654 struct cx8802_dev *dev = fe->dvb->priv;
655 dev->ts_gen_cntrl = 0;
657 return 0;
660 static int cx24116_reset_device(struct dvb_frontend *fe)
662 struct cx8802_dev *dev = fe->dvb->priv;
663 struct cx88_core *core = dev->core;
665 /* Reset the part */
666 /* Put the cx24116 into reset */
667 cx_write(MO_SRST_IO, 0);
668 msleep(10);
669 /* Take the cx24116 out of reset */
670 cx_write(MO_SRST_IO, 1);
671 msleep(10);
673 return 0;
676 static const struct cx24116_config hauppauge_hvr4000_config = {
677 .demod_address = 0x05,
678 .set_ts_params = cx24116_set_ts_param,
679 .reset_device = cx24116_reset_device,
682 static const struct cx24116_config tevii_s460_config = {
683 .demod_address = 0x55,
684 .set_ts_params = cx24116_set_ts_param,
685 .reset_device = cx24116_reset_device,
688 static int ds3000_set_ts_param(struct dvb_frontend *fe,
689 int is_punctured)
691 struct cx8802_dev *dev = fe->dvb->priv;
692 dev->ts_gen_cntrl = 4;
694 return 0;
697 static struct ds3000_config tevii_ds3000_config = {
698 .demod_address = 0x68,
699 .set_ts_params = ds3000_set_ts_param,
702 static const struct stv0900_config prof_7301_stv0900_config = {
703 .demod_address = 0x6a,
704 /* demod_mode = 0,*/
705 .xtal = 27000000,
706 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
707 .diseqc_mode = 2,/* 2/3 PWM */
708 .tun1_maddress = 0,/* 0x60 */
709 .tun1_adc = 0,/* 2 Vpp */
710 .path1_mode = 3,
711 .set_ts_params = stv0900_set_ts_param,
714 static const struct stb6100_config prof_7301_stb6100_config = {
715 .tuner_address = 0x60,
716 .refclock = 27000000,
719 static const struct stv0299_config tevii_tuner_sharp_config = {
720 .demod_address = 0x68,
721 .inittab = sharp_z0194a_inittab,
722 .mclk = 88000000UL,
723 .invert = 1,
724 .skip_reinit = 0,
725 .lock_output = 1,
726 .volt13_op0_op1 = STV0299_VOLT13_OP1,
727 .min_delay_ms = 100,
728 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
729 .set_ts_params = cx24116_set_ts_param,
732 static const struct stv0288_config tevii_tuner_earda_config = {
733 .demod_address = 0x68,
734 .min_delay_ms = 100,
735 .set_ts_params = cx24116_set_ts_param,
738 static int cx8802_alloc_frontends(struct cx8802_dev *dev)
740 struct cx88_core *core = dev->core;
741 struct videobuf_dvb_frontend *fe = NULL;
742 int i;
744 mutex_init(&dev->frontends.lock);
745 INIT_LIST_HEAD(&dev->frontends.felist);
747 if (!core->board.num_frontends)
748 return -ENODEV;
750 printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
751 core->board.num_frontends);
752 for (i = 1; i <= core->board.num_frontends; i++) {
753 fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
754 if (!fe) {
755 printk(KERN_ERR "%s() failed to alloc\n", __func__);
756 videobuf_dvb_dealloc_frontends(&dev->frontends);
757 return -ENOMEM;
760 return 0;
765 static const u8 samsung_smt_7020_inittab[] = {
766 0x01, 0x15,
767 0x02, 0x00,
768 0x03, 0x00,
769 0x04, 0x7D,
770 0x05, 0x0F,
771 0x06, 0x02,
772 0x07, 0x00,
773 0x08, 0x60,
775 0x0A, 0xC2,
776 0x0B, 0x00,
777 0x0C, 0x01,
778 0x0D, 0x81,
779 0x0E, 0x44,
780 0x0F, 0x09,
781 0x10, 0x3C,
782 0x11, 0x84,
783 0x12, 0xDA,
784 0x13, 0x99,
785 0x14, 0x8D,
786 0x15, 0xCE,
787 0x16, 0xE8,
788 0x17, 0x43,
789 0x18, 0x1C,
790 0x19, 0x1B,
791 0x1A, 0x1D,
793 0x1C, 0x12,
794 0x1D, 0x00,
795 0x1E, 0x00,
796 0x1F, 0x00,
797 0x20, 0x00,
798 0x21, 0x00,
799 0x22, 0x00,
800 0x23, 0x00,
802 0x28, 0x02,
803 0x29, 0x28,
804 0x2A, 0x14,
805 0x2B, 0x0F,
806 0x2C, 0x09,
807 0x2D, 0x05,
809 0x31, 0x1F,
810 0x32, 0x19,
811 0x33, 0xFC,
812 0x34, 0x13,
813 0xff, 0xff,
817 static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
818 struct dvb_frontend_parameters *params)
820 struct cx8802_dev *dev = fe->dvb->priv;
821 u8 buf[4];
822 u32 div;
823 struct i2c_msg msg = {
824 .addr = 0x61,
825 .flags = 0,
826 .buf = buf,
827 .len = sizeof(buf) };
829 div = params->frequency / 125;
831 buf[0] = (div >> 8) & 0x7f;
832 buf[1] = div & 0xff;
833 buf[2] = 0x84; /* 0xC4 */
834 buf[3] = 0x00;
836 if (params->frequency < 1500000)
837 buf[3] |= 0x10;
839 if (fe->ops.i2c_gate_ctrl)
840 fe->ops.i2c_gate_ctrl(fe, 1);
842 if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
843 return -EIO;
845 return 0;
848 static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
849 fe_sec_tone_mode_t tone)
851 struct cx8802_dev *dev = fe->dvb->priv;
852 struct cx88_core *core = dev->core;
854 cx_set(MO_GP0_IO, 0x0800);
856 switch (tone) {
857 case SEC_TONE_ON:
858 cx_set(MO_GP0_IO, 0x08);
859 break;
860 case SEC_TONE_OFF:
861 cx_clear(MO_GP0_IO, 0x08);
862 break;
863 default:
864 return -EINVAL;
867 return 0;
870 static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
871 fe_sec_voltage_t voltage)
873 struct cx8802_dev *dev = fe->dvb->priv;
874 struct cx88_core *core = dev->core;
876 u8 data;
877 struct i2c_msg msg = {
878 .addr = 8,
879 .flags = 0,
880 .buf = &data,
881 .len = sizeof(data) };
883 cx_set(MO_GP0_IO, 0x8000);
885 switch (voltage) {
886 case SEC_VOLTAGE_OFF:
887 break;
888 case SEC_VOLTAGE_13:
889 data = ISL6421_EN1 | ISL6421_LLC1;
890 cx_clear(MO_GP0_IO, 0x80);
891 break;
892 case SEC_VOLTAGE_18:
893 data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
894 cx_clear(MO_GP0_IO, 0x80);
895 break;
896 default:
897 return -EINVAL;
900 return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
903 static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
904 u32 srate, u32 ratio)
906 u8 aclk = 0;
907 u8 bclk = 0;
909 if (srate < 1500000) {
910 aclk = 0xb7;
911 bclk = 0x47;
912 } else if (srate < 3000000) {
913 aclk = 0xb7;
914 bclk = 0x4b;
915 } else if (srate < 7000000) {
916 aclk = 0xb7;
917 bclk = 0x4f;
918 } else if (srate < 14000000) {
919 aclk = 0xb7;
920 bclk = 0x53;
921 } else if (srate < 30000000) {
922 aclk = 0xb6;
923 bclk = 0x53;
924 } else if (srate < 45000000) {
925 aclk = 0xb4;
926 bclk = 0x51;
929 stv0299_writereg(fe, 0x13, aclk);
930 stv0299_writereg(fe, 0x14, bclk);
931 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
932 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
933 stv0299_writereg(fe, 0x21, ratio & 0xf0);
935 return 0;
939 static const struct stv0299_config samsung_stv0299_config = {
940 .demod_address = 0x68,
941 .inittab = samsung_smt_7020_inittab,
942 .mclk = 88000000UL,
943 .invert = 0,
944 .skip_reinit = 0,
945 .lock_output = STV0299_LOCKOUTPUT_LK,
946 .volt13_op0_op1 = STV0299_VOLT13_OP1,
947 .min_delay_ms = 100,
948 .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
951 static int dvb_register(struct cx8802_dev *dev)
953 struct cx88_core *core = dev->core;
954 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
955 int mfe_shared = 0; /* bus not shared by default */
957 if (0 != core->i2c_rc) {
958 printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
959 goto frontend_detach;
962 /* Get the first frontend */
963 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
964 if (!fe0)
965 goto frontend_detach;
967 /* multi-frontend gate control is undefined or defaults to fe0 */
968 dev->frontends.gate = 0;
970 /* Sets the gate control callback to be used by i2c command calls */
971 core->gate_ctrl = cx88_dvb_gate_ctrl;
973 /* init frontend(s) */
974 switch (core->boardnr) {
975 case CX88_BOARD_HAUPPAUGE_DVB_T1:
976 fe0->dvb.frontend = dvb_attach(cx22702_attach,
977 &connexant_refboard_config,
978 &core->i2c_adap);
979 if (fe0->dvb.frontend != NULL) {
980 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
981 0x61, &core->i2c_adap,
982 DVB_PLL_THOMSON_DTT759X))
983 goto frontend_detach;
985 break;
986 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
987 case CX88_BOARD_CONEXANT_DVB_T1:
988 case CX88_BOARD_KWORLD_DVB_T_CX22702:
989 case CX88_BOARD_WINFAST_DTV1000:
990 fe0->dvb.frontend = dvb_attach(cx22702_attach,
991 &connexant_refboard_config,
992 &core->i2c_adap);
993 if (fe0->dvb.frontend != NULL) {
994 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
995 0x60, &core->i2c_adap,
996 DVB_PLL_THOMSON_DTT7579))
997 goto frontend_detach;
999 break;
1000 case CX88_BOARD_WINFAST_DTV2000H:
1001 case CX88_BOARD_WINFAST_DTV2000H_J:
1002 case CX88_BOARD_HAUPPAUGE_HVR1100:
1003 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
1004 case CX88_BOARD_HAUPPAUGE_HVR1300:
1005 fe0->dvb.frontend = dvb_attach(cx22702_attach,
1006 &hauppauge_hvr_config,
1007 &core->i2c_adap);
1008 if (fe0->dvb.frontend != NULL) {
1009 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1010 &core->i2c_adap, 0x61,
1011 TUNER_PHILIPS_FMD1216ME_MK3))
1012 goto frontend_detach;
1014 break;
1015 case CX88_BOARD_HAUPPAUGE_HVR3000:
1016 /* MFE frontend 1 */
1017 mfe_shared = 1;
1018 dev->frontends.gate = 2;
1019 /* DVB-S init */
1020 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1021 &hauppauge_novas_config,
1022 &dev->core->i2c_adap);
1023 if (fe0->dvb.frontend) {
1024 if (!dvb_attach(isl6421_attach,
1025 fe0->dvb.frontend,
1026 &dev->core->i2c_adap,
1027 0x08, ISL6421_DCL, 0x00))
1028 goto frontend_detach;
1030 /* MFE frontend 2 */
1031 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1032 if (!fe1)
1033 goto frontend_detach;
1034 /* DVB-T init */
1035 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1036 &hauppauge_hvr_config,
1037 &dev->core->i2c_adap);
1038 if (fe1->dvb.frontend) {
1039 fe1->dvb.frontend->id = 1;
1040 if (!dvb_attach(simple_tuner_attach,
1041 fe1->dvb.frontend,
1042 &dev->core->i2c_adap,
1043 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1044 goto frontend_detach;
1046 break;
1047 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
1048 fe0->dvb.frontend = dvb_attach(mt352_attach,
1049 &dvico_fusionhdtv,
1050 &core->i2c_adap);
1051 if (fe0->dvb.frontend != NULL) {
1052 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1053 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1054 goto frontend_detach;
1055 break;
1057 /* ZL10353 replaces MT352 on later cards */
1058 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1059 &dvico_fusionhdtv_plus_v1_1,
1060 &core->i2c_adap);
1061 if (fe0->dvb.frontend != NULL) {
1062 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1063 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1064 goto frontend_detach;
1066 break;
1067 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1068 /* The tin box says DEE1601, but it seems to be DTT7579
1069 * compatible, with a slightly different MT352 AGC gain. */
1070 fe0->dvb.frontend = dvb_attach(mt352_attach,
1071 &dvico_fusionhdtv_dual,
1072 &core->i2c_adap);
1073 if (fe0->dvb.frontend != NULL) {
1074 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1075 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1076 goto frontend_detach;
1077 break;
1079 /* ZL10353 replaces MT352 on later cards */
1080 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1081 &dvico_fusionhdtv_plus_v1_1,
1082 &core->i2c_adap);
1083 if (fe0->dvb.frontend != NULL) {
1084 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1085 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1086 goto frontend_detach;
1088 break;
1089 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
1090 fe0->dvb.frontend = dvb_attach(mt352_attach,
1091 &dvico_fusionhdtv,
1092 &core->i2c_adap);
1093 if (fe0->dvb.frontend != NULL) {
1094 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1095 0x61, NULL, DVB_PLL_LG_Z201))
1096 goto frontend_detach;
1098 break;
1099 case CX88_BOARD_KWORLD_DVB_T:
1100 case CX88_BOARD_DNTV_LIVE_DVB_T:
1101 case CX88_BOARD_ADSTECH_DVB_T_PCI:
1102 fe0->dvb.frontend = dvb_attach(mt352_attach,
1103 &dntv_live_dvbt_config,
1104 &core->i2c_adap);
1105 if (fe0->dvb.frontend != NULL) {
1106 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1107 0x61, NULL, DVB_PLL_UNKNOWN_1))
1108 goto frontend_detach;
1110 break;
1111 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
1112 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
1113 /* MT352 is on a secondary I2C bus made from some GPIO lines */
1114 fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
1115 &dev->vp3054->adap);
1116 if (fe0->dvb.frontend != NULL) {
1117 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1118 &core->i2c_adap, 0x61,
1119 TUNER_PHILIPS_FMD1216ME_MK3))
1120 goto frontend_detach;
1122 #else
1123 printk(KERN_ERR "%s/2: built without vp3054 support\n",
1124 core->name);
1125 #endif
1126 break;
1127 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
1128 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1129 &dvico_fusionhdtv_hybrid,
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_THOMSON_FE6600))
1135 goto frontend_detach;
1137 break;
1138 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
1139 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1140 &dvico_fusionhdtv_xc3028,
1141 &core->i2c_adap);
1142 if (fe0->dvb.frontend == NULL)
1143 fe0->dvb.frontend = dvb_attach(mt352_attach,
1144 &dvico_fusionhdtv_mt352_xc3028,
1145 &core->i2c_adap);
1147 * On this board, the demod provides the I2C bus pullup.
1148 * We must not permit gate_ctrl to be performed, or
1149 * the xc3028 cannot communicate on the bus.
1151 if (fe0->dvb.frontend)
1152 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1153 if (attach_xc3028(0x61, dev) < 0)
1154 goto frontend_detach;
1155 break;
1156 case CX88_BOARD_PCHDTV_HD3000:
1157 fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
1158 &core->i2c_adap);
1159 if (fe0->dvb.frontend != NULL) {
1160 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1161 &core->i2c_adap, 0x61,
1162 TUNER_THOMSON_DTT761X))
1163 goto frontend_detach;
1165 break;
1166 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
1167 dev->ts_gen_cntrl = 0x08;
1169 /* Do a hardware reset of chip before using it. */
1170 cx_clear(MO_GP0_IO, 1);
1171 mdelay(100);
1172 cx_set(MO_GP0_IO, 1);
1173 mdelay(200);
1175 /* Select RF connector callback */
1176 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
1177 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1178 &fusionhdtv_3_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_MICROTUNE_4042FI5))
1184 goto frontend_detach;
1186 break;
1187 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
1188 dev->ts_gen_cntrl = 0x08;
1190 /* Do a hardware reset of chip before using it. */
1191 cx_clear(MO_GP0_IO, 1);
1192 mdelay(100);
1193 cx_set(MO_GP0_IO, 9);
1194 mdelay(200);
1195 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1196 &fusionhdtv_3_gold,
1197 &core->i2c_adap);
1198 if (fe0->dvb.frontend != NULL) {
1199 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1200 &core->i2c_adap, 0x61,
1201 TUNER_THOMSON_DTT761X))
1202 goto frontend_detach;
1204 break;
1205 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
1206 dev->ts_gen_cntrl = 0x08;
1208 /* Do a hardware reset of chip before using it. */
1209 cx_clear(MO_GP0_IO, 1);
1210 mdelay(100);
1211 cx_set(MO_GP0_IO, 1);
1212 mdelay(200);
1213 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1214 &fusionhdtv_5_gold,
1215 &core->i2c_adap);
1216 if (fe0->dvb.frontend != NULL) {
1217 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1218 &core->i2c_adap, 0x61,
1219 TUNER_LG_TDVS_H06XF))
1220 goto frontend_detach;
1221 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1222 &core->i2c_adap, 0x43))
1223 goto frontend_detach;
1225 break;
1226 case CX88_BOARD_PCHDTV_HD5500:
1227 dev->ts_gen_cntrl = 0x08;
1229 /* Do a hardware reset of chip before using it. */
1230 cx_clear(MO_GP0_IO, 1);
1231 mdelay(100);
1232 cx_set(MO_GP0_IO, 1);
1233 mdelay(200);
1234 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1235 &pchdtv_hd5500,
1236 &core->i2c_adap);
1237 if (fe0->dvb.frontend != NULL) {
1238 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1239 &core->i2c_adap, 0x61,
1240 TUNER_LG_TDVS_H06XF))
1241 goto frontend_detach;
1242 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1243 &core->i2c_adap, 0x43))
1244 goto frontend_detach;
1246 break;
1247 case CX88_BOARD_ATI_HDTVWONDER:
1248 fe0->dvb.frontend = dvb_attach(nxt200x_attach,
1249 &ati_hdtvwonder,
1250 &core->i2c_adap);
1251 if (fe0->dvb.frontend != NULL) {
1252 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1253 &core->i2c_adap, 0x61,
1254 TUNER_PHILIPS_TUV1236D))
1255 goto frontend_detach;
1257 break;
1258 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
1259 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
1260 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1261 &hauppauge_novas_config,
1262 &core->i2c_adap);
1263 if (fe0->dvb.frontend) {
1264 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
1265 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
1266 goto frontend_detach;
1268 break;
1269 case CX88_BOARD_KWORLD_DVBS_100:
1270 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1271 &kworld_dvbs_100_config,
1272 &core->i2c_adap);
1273 if (fe0->dvb.frontend) {
1274 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1275 fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
1277 break;
1278 case CX88_BOARD_GENIATECH_DVBS:
1279 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1280 &geniatech_dvbs_config,
1281 &core->i2c_adap);
1282 if (fe0->dvb.frontend) {
1283 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1284 fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
1286 break;
1287 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
1288 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1289 &pinnacle_pctv_hd_800i_config,
1290 &core->i2c_adap);
1291 if (fe0->dvb.frontend != NULL) {
1292 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1293 &core->i2c_adap,
1294 &pinnacle_pctv_hd_800i_tuner_config))
1295 goto frontend_detach;
1297 break;
1298 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
1299 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1300 &dvico_hdtv5_pci_nano_config,
1301 &core->i2c_adap);
1302 if (fe0->dvb.frontend != NULL) {
1303 struct dvb_frontend *fe;
1304 struct xc2028_config cfg = {
1305 .i2c_adap = &core->i2c_adap,
1306 .i2c_addr = 0x61,
1308 static struct xc2028_ctrl ctl = {
1309 .fname = XC2028_DEFAULT_FIRMWARE,
1310 .max_len = 64,
1311 .scode_table = XC3028_FE_OREN538,
1314 fe = dvb_attach(xc2028_attach,
1315 fe0->dvb.frontend, &cfg);
1316 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1317 fe->ops.tuner_ops.set_config(fe, &ctl);
1319 break;
1320 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
1321 case CX88_BOARD_WINFAST_DTV1800H:
1322 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1323 &cx88_pinnacle_hybrid_pctv,
1324 &core->i2c_adap);
1325 if (fe0->dvb.frontend) {
1326 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1327 if (attach_xc3028(0x61, dev) < 0)
1328 goto frontend_detach;
1330 break;
1331 case CX88_BOARD_GENIATECH_X8000_MT:
1332 dev->ts_gen_cntrl = 0x00;
1334 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1335 &cx88_geniatech_x8000_mt,
1336 &core->i2c_adap);
1337 if (attach_xc3028(0x61, dev) < 0)
1338 goto frontend_detach;
1339 break;
1340 case CX88_BOARD_KWORLD_ATSC_120:
1341 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1342 &kworld_atsc_120_config,
1343 &core->i2c_adap);
1344 if (attach_xc3028(0x61, dev) < 0)
1345 goto frontend_detach;
1346 break;
1347 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
1348 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1349 &dvico_fusionhdtv7_config,
1350 &core->i2c_adap);
1351 if (fe0->dvb.frontend != NULL) {
1352 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1353 &core->i2c_adap,
1354 &dvico_fusionhdtv7_tuner_config))
1355 goto frontend_detach;
1357 break;
1358 case CX88_BOARD_HAUPPAUGE_HVR4000:
1359 /* MFE frontend 1 */
1360 mfe_shared = 1;
1361 dev->frontends.gate = 2;
1362 /* DVB-S/S2 Init */
1363 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1364 &hauppauge_hvr4000_config,
1365 &dev->core->i2c_adap);
1366 if (fe0->dvb.frontend) {
1367 if (!dvb_attach(isl6421_attach,
1368 fe0->dvb.frontend,
1369 &dev->core->i2c_adap,
1370 0x08, ISL6421_DCL, 0x00))
1371 goto frontend_detach;
1373 /* MFE frontend 2 */
1374 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1375 if (!fe1)
1376 goto frontend_detach;
1377 /* DVB-T Init */
1378 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1379 &hauppauge_hvr_config,
1380 &dev->core->i2c_adap);
1381 if (fe1->dvb.frontend) {
1382 fe1->dvb.frontend->id = 1;
1383 if (!dvb_attach(simple_tuner_attach,
1384 fe1->dvb.frontend,
1385 &dev->core->i2c_adap,
1386 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1387 goto frontend_detach;
1389 break;
1390 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
1391 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1392 &hauppauge_hvr4000_config,
1393 &dev->core->i2c_adap);
1394 if (fe0->dvb.frontend) {
1395 if (!dvb_attach(isl6421_attach,
1396 fe0->dvb.frontend,
1397 &dev->core->i2c_adap,
1398 0x08, ISL6421_DCL, 0x00))
1399 goto frontend_detach;
1401 break;
1402 case CX88_BOARD_PROF_6200:
1403 case CX88_BOARD_TBS_8910:
1404 case CX88_BOARD_TEVII_S420:
1405 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1406 &tevii_tuner_sharp_config,
1407 &core->i2c_adap);
1408 if (fe0->dvb.frontend != NULL) {
1409 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
1410 &core->i2c_adap, DVB_PLL_OPERA1))
1411 goto frontend_detach;
1412 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1413 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1415 } else {
1416 fe0->dvb.frontend = dvb_attach(stv0288_attach,
1417 &tevii_tuner_earda_config,
1418 &core->i2c_adap);
1419 if (fe0->dvb.frontend != NULL) {
1420 if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
1421 &core->i2c_adap))
1422 goto frontend_detach;
1423 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1424 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1427 break;
1428 case CX88_BOARD_TEVII_S460:
1429 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1430 &tevii_s460_config,
1431 &core->i2c_adap);
1432 if (fe0->dvb.frontend != NULL)
1433 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1434 break;
1435 case CX88_BOARD_TEVII_S464:
1436 fe0->dvb.frontend = dvb_attach(ds3000_attach,
1437 &tevii_ds3000_config,
1438 &core->i2c_adap);
1439 if (fe0->dvb.frontend != NULL)
1440 fe0->dvb.frontend->ops.set_voltage =
1441 tevii_dvbs_set_voltage;
1442 break;
1443 case CX88_BOARD_OMICOM_SS4_PCI:
1444 case CX88_BOARD_TBS_8920:
1445 case CX88_BOARD_PROF_7300:
1446 case CX88_BOARD_SATTRADE_ST4200:
1447 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1448 &hauppauge_hvr4000_config,
1449 &core->i2c_adap);
1450 if (fe0->dvb.frontend != NULL)
1451 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1452 break;
1453 case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
1454 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1455 &cx88_terratec_cinergy_ht_pci_mkii_config,
1456 &core->i2c_adap);
1457 if (fe0->dvb.frontend) {
1458 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1459 if (attach_xc3028(0x61, dev) < 0)
1460 goto frontend_detach;
1462 break;
1463 case CX88_BOARD_PROF_7301:{
1464 struct dvb_tuner_ops *tuner_ops = NULL;
1466 fe0->dvb.frontend = dvb_attach(stv0900_attach,
1467 &prof_7301_stv0900_config,
1468 &core->i2c_adap, 0);
1469 if (fe0->dvb.frontend != NULL) {
1470 if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
1471 &prof_7301_stb6100_config,
1472 &core->i2c_adap))
1473 goto frontend_detach;
1475 tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
1476 tuner_ops->set_frequency = stb6100_set_freq;
1477 tuner_ops->get_frequency = stb6100_get_freq;
1478 tuner_ops->set_bandwidth = stb6100_set_bandw;
1479 tuner_ops->get_bandwidth = stb6100_get_bandw;
1481 core->prev_set_voltage =
1482 fe0->dvb.frontend->ops.set_voltage;
1483 fe0->dvb.frontend->ops.set_voltage =
1484 tevii_dvbs_set_voltage;
1486 break;
1488 case CX88_BOARD_SAMSUNG_SMT_7020:
1489 dev->ts_gen_cntrl = 0x08;
1491 cx_set(MO_GP0_IO, 0x0101);
1493 cx_clear(MO_GP0_IO, 0x01);
1494 mdelay(100);
1495 cx_set(MO_GP0_IO, 0x01);
1496 mdelay(200);
1498 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1499 &samsung_stv0299_config,
1500 &dev->core->i2c_adap);
1501 if (fe0->dvb.frontend) {
1502 fe0->dvb.frontend->ops.tuner_ops.set_params =
1503 samsung_smt_7020_tuner_set_params;
1504 fe0->dvb.frontend->tuner_priv =
1505 &dev->core->i2c_adap;
1506 fe0->dvb.frontend->ops.set_voltage =
1507 samsung_smt_7020_set_voltage;
1508 fe0->dvb.frontend->ops.set_tone =
1509 samsung_smt_7020_set_tone;
1512 break;
1513 case CX88_BOARD_TWINHAN_VP1027_DVBS:
1514 dev->ts_gen_cntrl = 0x00;
1515 fe0->dvb.frontend = dvb_attach(mb86a16_attach,
1516 &twinhan_vp1027,
1517 &core->i2c_adap);
1518 if (fe0->dvb.frontend) {
1519 core->prev_set_voltage =
1520 fe0->dvb.frontend->ops.set_voltage;
1521 fe0->dvb.frontend->ops.set_voltage =
1522 vp1027_set_voltage;
1524 break;
1526 default:
1527 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1528 core->name);
1529 break;
1532 if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
1533 printk(KERN_ERR
1534 "%s/2: frontend initialization failed\n",
1535 core->name);
1536 goto frontend_detach;
1538 /* define general-purpose callback pointer */
1539 fe0->dvb.frontend->callback = cx88_tuner_callback;
1541 /* Ensure all frontends negotiate bus access */
1542 fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1543 if (fe1)
1544 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1546 /* Put the analog decoder in standby to keep it quiet */
1547 call_all(core, core, s_power, 0);
1549 /* register everything */
1550 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1551 &dev->pci->dev, adapter_nr, mfe_shared, NULL);
1553 frontend_detach:
1554 core->gate_ctrl = NULL;
1555 videobuf_dvb_dealloc_frontends(&dev->frontends);
1556 return -EINVAL;
1559 /* ----------------------------------------------------------- */
1561 /* CX8802 MPEG -> mini driver - We have been given the hardware */
1562 static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
1564 struct cx88_core *core = drv->core;
1565 int err = 0;
1566 dprintk( 1, "%s\n", __func__);
1568 switch (core->boardnr) {
1569 case CX88_BOARD_HAUPPAUGE_HVR1300:
1570 /* We arrive here with either the cx23416 or the cx22702
1571 * on the bus. Take the bus from the cx23416 and enable the
1572 * cx22702 demod
1574 /* Toggle reset on cx22702 leaving i2c active */
1575 cx_set(MO_GP0_IO, 0x00000080);
1576 udelay(1000);
1577 cx_clear(MO_GP0_IO, 0x00000080);
1578 udelay(50);
1579 cx_set(MO_GP0_IO, 0x00000080);
1580 udelay(1000);
1581 /* enable the cx22702 pins */
1582 cx_clear(MO_GP0_IO, 0x00000004);
1583 udelay(1000);
1584 break;
1586 case CX88_BOARD_HAUPPAUGE_HVR3000:
1587 case CX88_BOARD_HAUPPAUGE_HVR4000:
1588 /* Toggle reset on cx22702 leaving i2c active */
1589 cx_set(MO_GP0_IO, 0x00000080);
1590 udelay(1000);
1591 cx_clear(MO_GP0_IO, 0x00000080);
1592 udelay(50);
1593 cx_set(MO_GP0_IO, 0x00000080);
1594 udelay(1000);
1595 switch (core->dvbdev->frontends.active_fe_id) {
1596 case 1: /* DVB-S/S2 Enabled */
1597 /* tri-state the cx22702 pins */
1598 cx_set(MO_GP0_IO, 0x00000004);
1599 /* Take the cx24116/cx24123 out of reset */
1600 cx_write(MO_SRST_IO, 1);
1601 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1602 break;
1603 case 2: /* DVB-T Enabled */
1604 /* Put the cx24116/cx24123 into reset */
1605 cx_write(MO_SRST_IO, 0);
1606 /* enable the cx22702 pins */
1607 cx_clear(MO_GP0_IO, 0x00000004);
1608 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1609 break;
1611 udelay(1000);
1612 break;
1614 default:
1615 err = -ENODEV;
1617 return err;
1620 /* CX8802 MPEG -> mini driver - We no longer have the hardware */
1621 static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
1623 struct cx88_core *core = drv->core;
1624 int err = 0;
1625 dprintk( 1, "%s\n", __func__);
1627 switch (core->boardnr) {
1628 case CX88_BOARD_HAUPPAUGE_HVR1300:
1629 /* Do Nothing, leave the cx22702 on the bus. */
1630 break;
1631 case CX88_BOARD_HAUPPAUGE_HVR3000:
1632 case CX88_BOARD_HAUPPAUGE_HVR4000:
1633 break;
1634 default:
1635 err = -ENODEV;
1637 return err;
1640 static int cx8802_dvb_probe(struct cx8802_driver *drv)
1642 struct cx88_core *core = drv->core;
1643 struct cx8802_dev *dev = drv->core->dvbdev;
1644 int err;
1645 struct videobuf_dvb_frontend *fe;
1646 int i;
1648 dprintk( 1, "%s\n", __func__);
1649 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1650 core->boardnr,
1651 core->name,
1652 core->pci_bus,
1653 core->pci_slot);
1655 err = -ENODEV;
1656 if (!(core->board.mpeg & CX88_MPEG_DVB))
1657 goto fail_core;
1659 /* If vp3054 isn't enabled, a stub will just return 0 */
1660 err = vp3054_i2c_probe(dev);
1661 if (0 != err)
1662 goto fail_core;
1664 /* dvb stuff */
1665 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1666 dev->ts_gen_cntrl = 0x0c;
1668 err = cx8802_alloc_frontends(dev);
1669 if (err)
1670 goto fail_core;
1672 err = -ENODEV;
1673 for (i = 1; i <= core->board.num_frontends; i++) {
1674 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
1675 if (fe == NULL) {
1676 printk(KERN_ERR "%s() failed to get frontend(%d)\n",
1677 __func__, i);
1678 goto fail_probe;
1680 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
1681 &dev->pci->dev, &dev->slock,
1682 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1683 V4L2_FIELD_TOP,
1684 sizeof(struct cx88_buffer),
1685 dev, NULL);
1686 /* init struct videobuf_dvb */
1687 fe->dvb.name = dev->core->name;
1690 err = dvb_register(dev);
1691 if (err)
1692 /* frontends/adapter de-allocated in dvb_register */
1693 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
1694 core->name, err);
1695 return err;
1696 fail_probe:
1697 videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends);
1698 fail_core:
1699 return err;
1702 static int cx8802_dvb_remove(struct cx8802_driver *drv)
1704 struct cx88_core *core = drv->core;
1705 struct cx8802_dev *dev = drv->core->dvbdev;
1707 dprintk( 1, "%s\n", __func__);
1709 videobuf_dvb_unregister_bus(&dev->frontends);
1711 vp3054_i2c_remove(dev);
1713 core->gate_ctrl = NULL;
1715 return 0;
1718 static struct cx8802_driver cx8802_dvb_driver = {
1719 .type_id = CX88_MPEG_DVB,
1720 .hw_access = CX8802_DRVCTL_SHARED,
1721 .probe = cx8802_dvb_probe,
1722 .remove = cx8802_dvb_remove,
1723 .advise_acquire = cx8802_dvb_advise_acquire,
1724 .advise_release = cx8802_dvb_advise_release,
1727 static int __init dvb_init(void)
1729 printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n",
1730 (CX88_VERSION_CODE >> 16) & 0xff,
1731 (CX88_VERSION_CODE >> 8) & 0xff,
1732 CX88_VERSION_CODE & 0xff);
1733 #ifdef SNAPSHOT
1734 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
1735 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1736 #endif
1737 return cx8802_register_driver(&cx8802_dvb_driver);
1740 static void __exit dvb_fini(void)
1742 cx8802_unregister_driver(&cx8802_dvb_driver);
1745 module_init(dvb_init);
1746 module_exit(dvb_fini);
1749 * Local variables:
1750 * c-basic-offset: 8
1751 * compile-command: "make DVB=1"
1752 * End: