Merge branch 'v6v7' into devel
[linux/fpc-iii.git] / drivers / media / video / cx88 / cx88-dvb.c
blob90717ee944ec5632e62ae2d3462f7987718671db
1 /*
3 * device driver for Conexant 2388x based TV cards
4 * MPEG Transport Stream (DVB) routines
6 * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/device.h>
27 #include <linux/fs.h>
28 #include <linux/kthread.h>
29 #include <linux/file.h>
30 #include <linux/suspend.h>
32 #include "cx88.h"
33 #include "dvb-pll.h"
34 #include <media/v4l2-common.h>
36 #include "mt352.h"
37 #include "mt352_priv.h"
38 #include "cx88-vp3054-i2c.h"
39 #include "zl10353.h"
40 #include "cx22702.h"
41 #include "or51132.h"
42 #include "lgdt330x.h"
43 #include "s5h1409.h"
44 #include "xc5000.h"
45 #include "nxt200x.h"
46 #include "cx24123.h"
47 #include "isl6421.h"
48 #include "tuner-simple.h"
49 #include "tda9887.h"
50 #include "s5h1411.h"
51 #include "stv0299.h"
52 #include "z0194a.h"
53 #include "stv0288.h"
54 #include "stb6000.h"
55 #include "cx24116.h"
56 #include "stv0900.h"
57 #include "stb6100.h"
58 #include "stb6100_proc.h"
59 #include "mb86a16.h"
61 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
62 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
63 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
64 MODULE_LICENSE("GPL");
66 static unsigned int debug;
67 module_param(debug, int, 0644);
68 MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
70 static unsigned int dvb_buf_tscnt = 32;
71 module_param(dvb_buf_tscnt, int, 0644);
72 MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]");
74 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
76 #define dprintk(level,fmt, arg...) if (debug >= level) \
77 printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
79 /* ------------------------------------------------------------------ */
81 static int dvb_buf_setup(struct videobuf_queue *q,
82 unsigned int *count, unsigned int *size)
84 struct cx8802_dev *dev = q->priv_data;
86 dev->ts_packet_size = 188 * 4;
87 dev->ts_packet_count = dvb_buf_tscnt;
89 *size = dev->ts_packet_size * dev->ts_packet_count;
90 *count = dvb_buf_tscnt;
91 return 0;
94 static int dvb_buf_prepare(struct videobuf_queue *q,
95 struct videobuf_buffer *vb, enum v4l2_field field)
97 struct cx8802_dev *dev = q->priv_data;
98 return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
101 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
103 struct cx8802_dev *dev = q->priv_data;
104 cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
107 static void dvb_buf_release(struct videobuf_queue *q,
108 struct videobuf_buffer *vb)
110 cx88_free_buffer(q, (struct cx88_buffer*)vb);
113 static const struct videobuf_queue_ops dvb_qops = {
114 .buf_setup = dvb_buf_setup,
115 .buf_prepare = dvb_buf_prepare,
116 .buf_queue = dvb_buf_queue,
117 .buf_release = dvb_buf_release,
120 /* ------------------------------------------------------------------ */
122 static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
124 struct cx8802_dev *dev= fe->dvb->priv;
125 struct cx8802_driver *drv = NULL;
126 int ret = 0;
127 int fe_id;
129 fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
130 if (!fe_id) {
131 printk(KERN_ERR "%s() No frontend found\n", __func__);
132 return -EINVAL;
135 drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
136 if (drv) {
137 if (acquire){
138 dev->frontends.active_fe_id = fe_id;
139 ret = drv->request_acquire(drv);
140 } else {
141 ret = drv->request_release(drv);
142 dev->frontends.active_fe_id = 0;
146 return ret;
149 static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open)
151 struct videobuf_dvb_frontends *f;
152 struct videobuf_dvb_frontend *fe;
154 if (!core->dvbdev)
155 return;
157 f = &core->dvbdev->frontends;
159 if (!f)
160 return;
162 if (f->gate <= 1) /* undefined or fe0 */
163 fe = videobuf_dvb_get_frontend(f, 1);
164 else
165 fe = videobuf_dvb_get_frontend(f, f->gate);
167 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
168 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
171 /* ------------------------------------------------------------------ */
173 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
175 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
176 static const u8 reset [] = { RESET, 0x80 };
177 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
178 static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
179 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
180 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
182 mt352_write(fe, clock_config, sizeof(clock_config));
183 udelay(200);
184 mt352_write(fe, reset, sizeof(reset));
185 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
187 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
188 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
189 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
190 return 0;
193 static int dvico_dual_demod_init(struct dvb_frontend *fe)
195 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
196 static const u8 reset [] = { RESET, 0x80 };
197 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
198 static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
199 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
200 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
202 mt352_write(fe, clock_config, sizeof(clock_config));
203 udelay(200);
204 mt352_write(fe, reset, sizeof(reset));
205 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
207 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
208 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
209 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
211 return 0;
214 static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
216 static const u8 clock_config [] = { 0x89, 0x38, 0x39 };
217 static const u8 reset [] = { 0x50, 0x80 };
218 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
219 static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
220 0x00, 0xFF, 0x00, 0x40, 0x40 };
221 static const u8 dntv_extra[] = { 0xB5, 0x7A };
222 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
224 mt352_write(fe, clock_config, sizeof(clock_config));
225 udelay(2000);
226 mt352_write(fe, reset, sizeof(reset));
227 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
229 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
230 udelay(2000);
231 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
232 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
234 return 0;
237 static const struct mt352_config dvico_fusionhdtv = {
238 .demod_address = 0x0f,
239 .demod_init = dvico_fusionhdtv_demod_init,
242 static const struct mt352_config dntv_live_dvbt_config = {
243 .demod_address = 0x0f,
244 .demod_init = dntv_live_dvbt_demod_init,
247 static const struct mt352_config dvico_fusionhdtv_dual = {
248 .demod_address = 0x0f,
249 .demod_init = dvico_dual_demod_init,
252 static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
253 .demod_address = (0x1e >> 1),
254 .no_tuner = 1,
255 .if2 = 45600,
258 static struct mb86a16_config twinhan_vp1027 = {
259 .demod_address = 0x08,
262 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
263 static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
265 static const u8 clock_config [] = { 0x89, 0x38, 0x38 };
266 static const u8 reset [] = { 0x50, 0x80 };
267 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
268 static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
269 0x00, 0xFF, 0x00, 0x40, 0x40 };
270 static const u8 dntv_extra[] = { 0xB5, 0x7A };
271 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
273 mt352_write(fe, clock_config, sizeof(clock_config));
274 udelay(2000);
275 mt352_write(fe, reset, sizeof(reset));
276 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
278 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
279 udelay(2000);
280 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
281 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
283 return 0;
286 static const struct mt352_config dntv_live_dvbt_pro_config = {
287 .demod_address = 0x0f,
288 .no_tuner = 1,
289 .demod_init = dntv_live_dvbt_pro_demod_init,
291 #endif
293 static const struct zl10353_config dvico_fusionhdtv_hybrid = {
294 .demod_address = 0x0f,
295 .no_tuner = 1,
298 static const struct zl10353_config dvico_fusionhdtv_xc3028 = {
299 .demod_address = 0x0f,
300 .if2 = 45600,
301 .no_tuner = 1,
304 static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
305 .demod_address = 0x0f,
306 .if2 = 4560,
307 .no_tuner = 1,
308 .demod_init = dvico_fusionhdtv_demod_init,
311 static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
312 .demod_address = 0x0f,
315 static const struct cx22702_config connexant_refboard_config = {
316 .demod_address = 0x43,
317 .output_mode = CX22702_SERIAL_OUTPUT,
320 static const struct cx22702_config hauppauge_hvr_config = {
321 .demod_address = 0x63,
322 .output_mode = CX22702_SERIAL_OUTPUT,
325 static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
327 struct cx8802_dev *dev= fe->dvb->priv;
328 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
329 return 0;
332 static const struct or51132_config pchdtv_hd3000 = {
333 .demod_address = 0x15,
334 .set_ts_params = or51132_set_ts_param,
337 static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
339 struct cx8802_dev *dev= fe->dvb->priv;
340 struct cx88_core *core = dev->core;
342 dprintk(1, "%s: index = %d\n", __func__, index);
343 if (index == 0)
344 cx_clear(MO_GP0_IO, 8);
345 else
346 cx_set(MO_GP0_IO, 8);
347 return 0;
350 static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
352 struct cx8802_dev *dev= fe->dvb->priv;
353 if (is_punctured)
354 dev->ts_gen_cntrl |= 0x04;
355 else
356 dev->ts_gen_cntrl &= ~0x04;
357 return 0;
360 static struct lgdt330x_config fusionhdtv_3_gold = {
361 .demod_address = 0x0e,
362 .demod_chip = LGDT3302,
363 .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
364 .set_ts_params = lgdt330x_set_ts_param,
367 static const struct lgdt330x_config fusionhdtv_5_gold = {
368 .demod_address = 0x0e,
369 .demod_chip = LGDT3303,
370 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
371 .set_ts_params = lgdt330x_set_ts_param,
374 static const struct lgdt330x_config pchdtv_hd5500 = {
375 .demod_address = 0x59,
376 .demod_chip = LGDT3303,
377 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
378 .set_ts_params = lgdt330x_set_ts_param,
381 static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
383 struct cx8802_dev *dev= fe->dvb->priv;
384 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
385 return 0;
388 static const struct nxt200x_config ati_hdtvwonder = {
389 .demod_address = 0x0a,
390 .set_ts_params = nxt200x_set_ts_param,
393 static int cx24123_set_ts_param(struct dvb_frontend* fe,
394 int is_punctured)
396 struct cx8802_dev *dev= fe->dvb->priv;
397 dev->ts_gen_cntrl = 0x02;
398 return 0;
401 static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
402 fe_sec_voltage_t voltage)
404 struct cx8802_dev *dev= fe->dvb->priv;
405 struct cx88_core *core = dev->core;
407 if (voltage == SEC_VOLTAGE_OFF)
408 cx_write(MO_GP0_IO, 0x000006fb);
409 else
410 cx_write(MO_GP0_IO, 0x000006f9);
412 if (core->prev_set_voltage)
413 return core->prev_set_voltage(fe, voltage);
414 return 0;
417 static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
418 fe_sec_voltage_t voltage)
420 struct cx8802_dev *dev= fe->dvb->priv;
421 struct cx88_core *core = dev->core;
423 if (voltage == SEC_VOLTAGE_OFF) {
424 dprintk(1,"LNB Voltage OFF\n");
425 cx_write(MO_GP0_IO, 0x0000efff);
428 if (core->prev_set_voltage)
429 return core->prev_set_voltage(fe, voltage);
430 return 0;
433 static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
434 fe_sec_voltage_t voltage)
436 struct cx8802_dev *dev= fe->dvb->priv;
437 struct cx88_core *core = dev->core;
439 cx_set(MO_GP0_IO, 0x6040);
440 switch (voltage) {
441 case SEC_VOLTAGE_13:
442 cx_clear(MO_GP0_IO, 0x20);
443 break;
444 case SEC_VOLTAGE_18:
445 cx_set(MO_GP0_IO, 0x20);
446 break;
447 case SEC_VOLTAGE_OFF:
448 cx_clear(MO_GP0_IO, 0x20);
449 break;
452 if (core->prev_set_voltage)
453 return core->prev_set_voltage(fe, voltage);
454 return 0;
457 static int vp1027_set_voltage(struct dvb_frontend *fe,
458 fe_sec_voltage_t voltage)
460 struct cx8802_dev *dev = fe->dvb->priv;
461 struct cx88_core *core = dev->core;
463 switch (voltage) {
464 case SEC_VOLTAGE_13:
465 dprintk(1, "LNB SEC Voltage=13\n");
466 cx_write(MO_GP0_IO, 0x00001220);
467 break;
468 case SEC_VOLTAGE_18:
469 dprintk(1, "LNB SEC Voltage=18\n");
470 cx_write(MO_GP0_IO, 0x00001222);
471 break;
472 case SEC_VOLTAGE_OFF:
473 dprintk(1, "LNB Voltage OFF\n");
474 cx_write(MO_GP0_IO, 0x00001230);
475 break;
478 if (core->prev_set_voltage)
479 return core->prev_set_voltage(fe, voltage);
480 return 0;
483 static const struct cx24123_config geniatech_dvbs_config = {
484 .demod_address = 0x55,
485 .set_ts_params = cx24123_set_ts_param,
488 static const struct cx24123_config hauppauge_novas_config = {
489 .demod_address = 0x55,
490 .set_ts_params = cx24123_set_ts_param,
493 static const struct cx24123_config kworld_dvbs_100_config = {
494 .demod_address = 0x15,
495 .set_ts_params = cx24123_set_ts_param,
496 .lnb_polarity = 1,
499 static const struct s5h1409_config pinnacle_pctv_hd_800i_config = {
500 .demod_address = 0x32 >> 1,
501 .output_mode = S5H1409_PARALLEL_OUTPUT,
502 .gpio = S5H1409_GPIO_ON,
503 .qam_if = 44000,
504 .inversion = S5H1409_INVERSION_OFF,
505 .status_mode = S5H1409_DEMODLOCKING,
506 .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
509 static const struct s5h1409_config dvico_hdtv5_pci_nano_config = {
510 .demod_address = 0x32 >> 1,
511 .output_mode = S5H1409_SERIAL_OUTPUT,
512 .gpio = S5H1409_GPIO_OFF,
513 .inversion = S5H1409_INVERSION_OFF,
514 .status_mode = S5H1409_DEMODLOCKING,
515 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
518 static const struct s5h1409_config kworld_atsc_120_config = {
519 .demod_address = 0x32 >> 1,
520 .output_mode = S5H1409_SERIAL_OUTPUT,
521 .gpio = S5H1409_GPIO_OFF,
522 .inversion = S5H1409_INVERSION_OFF,
523 .status_mode = S5H1409_DEMODLOCKING,
524 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
527 static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
528 .i2c_address = 0x64,
529 .if_khz = 5380,
532 static const struct zl10353_config cx88_pinnacle_hybrid_pctv = {
533 .demod_address = (0x1e >> 1),
534 .no_tuner = 1,
535 .if2 = 45600,
538 static const struct zl10353_config cx88_geniatech_x8000_mt = {
539 .demod_address = (0x1e >> 1),
540 .no_tuner = 1,
541 .disable_i2c_gate_ctrl = 1,
544 static const struct s5h1411_config dvico_fusionhdtv7_config = {
545 .output_mode = S5H1411_SERIAL_OUTPUT,
546 .gpio = S5H1411_GPIO_ON,
547 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
548 .qam_if = S5H1411_IF_44000,
549 .vsb_if = S5H1411_IF_44000,
550 .inversion = S5H1411_INVERSION_OFF,
551 .status_mode = S5H1411_DEMODLOCKING
554 static const struct xc5000_config dvico_fusionhdtv7_tuner_config = {
555 .i2c_address = 0xc2 >> 1,
556 .if_khz = 5380,
559 static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
561 struct dvb_frontend *fe;
562 struct videobuf_dvb_frontend *fe0 = NULL;
563 struct xc2028_ctrl ctl;
564 struct xc2028_config cfg = {
565 .i2c_adap = &dev->core->i2c_adap,
566 .i2c_addr = addr,
567 .ctrl = &ctl,
570 /* Get the first frontend */
571 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
572 if (!fe0)
573 return -EINVAL;
575 if (!fe0->dvb.frontend) {
576 printk(KERN_ERR "%s/2: dvb frontend not attached. "
577 "Can't attach xc3028\n",
578 dev->core->name);
579 return -EINVAL;
583 * Some xc3028 devices may be hidden by an I2C gate. This is known
584 * to happen with some s5h1409-based devices.
585 * Now that I2C gate is open, sets up xc3028 configuration
587 cx88_setup_xc3028(dev->core, &ctl);
589 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
590 if (!fe) {
591 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
592 dev->core->name);
593 dvb_frontend_detach(fe0->dvb.frontend);
594 dvb_unregister_frontend(fe0->dvb.frontend);
595 fe0->dvb.frontend = NULL;
596 return -EINVAL;
599 printk(KERN_INFO "%s/2: xc3028 attached\n",
600 dev->core->name);
602 return 0;
605 static int cx24116_set_ts_param(struct dvb_frontend *fe,
606 int is_punctured)
608 struct cx8802_dev *dev = fe->dvb->priv;
609 dev->ts_gen_cntrl = 0x2;
611 return 0;
614 static int stv0900_set_ts_param(struct dvb_frontend *fe,
615 int is_punctured)
617 struct cx8802_dev *dev = fe->dvb->priv;
618 dev->ts_gen_cntrl = 0;
620 return 0;
623 static int cx24116_reset_device(struct dvb_frontend *fe)
625 struct cx8802_dev *dev = fe->dvb->priv;
626 struct cx88_core *core = dev->core;
628 /* Reset the part */
629 /* Put the cx24116 into reset */
630 cx_write(MO_SRST_IO, 0);
631 msleep(10);
632 /* Take the cx24116 out of reset */
633 cx_write(MO_SRST_IO, 1);
634 msleep(10);
636 return 0;
639 static const struct cx24116_config hauppauge_hvr4000_config = {
640 .demod_address = 0x05,
641 .set_ts_params = cx24116_set_ts_param,
642 .reset_device = cx24116_reset_device,
645 static const struct cx24116_config tevii_s460_config = {
646 .demod_address = 0x55,
647 .set_ts_params = cx24116_set_ts_param,
648 .reset_device = cx24116_reset_device,
651 static const struct stv0900_config prof_7301_stv0900_config = {
652 .demod_address = 0x6a,
653 /* demod_mode = 0,*/
654 .xtal = 27000000,
655 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
656 .diseqc_mode = 2,/* 2/3 PWM */
657 .tun1_maddress = 0,/* 0x60 */
658 .tun1_adc = 0,/* 2 Vpp */
659 .path1_mode = 3,
660 .set_ts_params = stv0900_set_ts_param,
663 static const struct stb6100_config prof_7301_stb6100_config = {
664 .tuner_address = 0x60,
665 .refclock = 27000000,
668 static const struct stv0299_config tevii_tuner_sharp_config = {
669 .demod_address = 0x68,
670 .inittab = sharp_z0194a_inittab,
671 .mclk = 88000000UL,
672 .invert = 1,
673 .skip_reinit = 0,
674 .lock_output = 1,
675 .volt13_op0_op1 = STV0299_VOLT13_OP1,
676 .min_delay_ms = 100,
677 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
678 .set_ts_params = cx24116_set_ts_param,
681 static const struct stv0288_config tevii_tuner_earda_config = {
682 .demod_address = 0x68,
683 .min_delay_ms = 100,
684 .set_ts_params = cx24116_set_ts_param,
687 static int cx8802_alloc_frontends(struct cx8802_dev *dev)
689 struct cx88_core *core = dev->core;
690 struct videobuf_dvb_frontend *fe = NULL;
691 int i;
693 mutex_init(&dev->frontends.lock);
694 INIT_LIST_HEAD(&dev->frontends.felist);
696 if (!core->board.num_frontends)
697 return -ENODEV;
699 printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
700 core->board.num_frontends);
701 for (i = 1; i <= core->board.num_frontends; i++) {
702 fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
703 if (!fe) {
704 printk(KERN_ERR "%s() failed to alloc\n", __func__);
705 videobuf_dvb_dealloc_frontends(&dev->frontends);
706 return -ENOMEM;
709 return 0;
714 static const u8 samsung_smt_7020_inittab[] = {
715 0x01, 0x15,
716 0x02, 0x00,
717 0x03, 0x00,
718 0x04, 0x7D,
719 0x05, 0x0F,
720 0x06, 0x02,
721 0x07, 0x00,
722 0x08, 0x60,
724 0x0A, 0xC2,
725 0x0B, 0x00,
726 0x0C, 0x01,
727 0x0D, 0x81,
728 0x0E, 0x44,
729 0x0F, 0x09,
730 0x10, 0x3C,
731 0x11, 0x84,
732 0x12, 0xDA,
733 0x13, 0x99,
734 0x14, 0x8D,
735 0x15, 0xCE,
736 0x16, 0xE8,
737 0x17, 0x43,
738 0x18, 0x1C,
739 0x19, 0x1B,
740 0x1A, 0x1D,
742 0x1C, 0x12,
743 0x1D, 0x00,
744 0x1E, 0x00,
745 0x1F, 0x00,
746 0x20, 0x00,
747 0x21, 0x00,
748 0x22, 0x00,
749 0x23, 0x00,
751 0x28, 0x02,
752 0x29, 0x28,
753 0x2A, 0x14,
754 0x2B, 0x0F,
755 0x2C, 0x09,
756 0x2D, 0x05,
758 0x31, 0x1F,
759 0x32, 0x19,
760 0x33, 0xFC,
761 0x34, 0x13,
762 0xff, 0xff,
766 static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
767 struct dvb_frontend_parameters *params)
769 struct cx8802_dev *dev = fe->dvb->priv;
770 u8 buf[4];
771 u32 div;
772 struct i2c_msg msg = {
773 .addr = 0x61,
774 .flags = 0,
775 .buf = buf,
776 .len = sizeof(buf) };
778 div = params->frequency / 125;
780 buf[0] = (div >> 8) & 0x7f;
781 buf[1] = div & 0xff;
782 buf[2] = 0x84; /* 0xC4 */
783 buf[3] = 0x00;
785 if (params->frequency < 1500000)
786 buf[3] |= 0x10;
788 if (fe->ops.i2c_gate_ctrl)
789 fe->ops.i2c_gate_ctrl(fe, 1);
791 if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
792 return -EIO;
794 return 0;
797 static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
798 fe_sec_tone_mode_t tone)
800 struct cx8802_dev *dev = fe->dvb->priv;
801 struct cx88_core *core = dev->core;
803 cx_set(MO_GP0_IO, 0x0800);
805 switch (tone) {
806 case SEC_TONE_ON:
807 cx_set(MO_GP0_IO, 0x08);
808 break;
809 case SEC_TONE_OFF:
810 cx_clear(MO_GP0_IO, 0x08);
811 break;
812 default:
813 return -EINVAL;
816 return 0;
819 static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
820 fe_sec_voltage_t voltage)
822 struct cx8802_dev *dev = fe->dvb->priv;
823 struct cx88_core *core = dev->core;
825 u8 data;
826 struct i2c_msg msg = {
827 .addr = 8,
828 .flags = 0,
829 .buf = &data,
830 .len = sizeof(data) };
832 cx_set(MO_GP0_IO, 0x8000);
834 switch (voltage) {
835 case SEC_VOLTAGE_OFF:
836 break;
837 case SEC_VOLTAGE_13:
838 data = ISL6421_EN1 | ISL6421_LLC1;
839 cx_clear(MO_GP0_IO, 0x80);
840 break;
841 case SEC_VOLTAGE_18:
842 data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
843 cx_clear(MO_GP0_IO, 0x80);
844 break;
845 default:
846 return -EINVAL;
849 return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
852 static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
853 u32 srate, u32 ratio)
855 u8 aclk = 0;
856 u8 bclk = 0;
858 if (srate < 1500000) {
859 aclk = 0xb7;
860 bclk = 0x47;
861 } else if (srate < 3000000) {
862 aclk = 0xb7;
863 bclk = 0x4b;
864 } else if (srate < 7000000) {
865 aclk = 0xb7;
866 bclk = 0x4f;
867 } else if (srate < 14000000) {
868 aclk = 0xb7;
869 bclk = 0x53;
870 } else if (srate < 30000000) {
871 aclk = 0xb6;
872 bclk = 0x53;
873 } else if (srate < 45000000) {
874 aclk = 0xb4;
875 bclk = 0x51;
878 stv0299_writereg(fe, 0x13, aclk);
879 stv0299_writereg(fe, 0x14, bclk);
880 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
881 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
882 stv0299_writereg(fe, 0x21, ratio & 0xf0);
884 return 0;
888 static const struct stv0299_config samsung_stv0299_config = {
889 .demod_address = 0x68,
890 .inittab = samsung_smt_7020_inittab,
891 .mclk = 88000000UL,
892 .invert = 0,
893 .skip_reinit = 0,
894 .lock_output = STV0299_LOCKOUTPUT_LK,
895 .volt13_op0_op1 = STV0299_VOLT13_OP1,
896 .min_delay_ms = 100,
897 .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
900 static int dvb_register(struct cx8802_dev *dev)
902 struct cx88_core *core = dev->core;
903 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
904 int mfe_shared = 0; /* bus not shared by default */
906 if (0 != core->i2c_rc) {
907 printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
908 goto frontend_detach;
911 /* Get the first frontend */
912 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
913 if (!fe0)
914 goto frontend_detach;
916 /* multi-frontend gate control is undefined or defaults to fe0 */
917 dev->frontends.gate = 0;
919 /* Sets the gate control callback to be used by i2c command calls */
920 core->gate_ctrl = cx88_dvb_gate_ctrl;
922 /* init frontend(s) */
923 switch (core->boardnr) {
924 case CX88_BOARD_HAUPPAUGE_DVB_T1:
925 fe0->dvb.frontend = dvb_attach(cx22702_attach,
926 &connexant_refboard_config,
927 &core->i2c_adap);
928 if (fe0->dvb.frontend != NULL) {
929 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
930 0x61, &core->i2c_adap,
931 DVB_PLL_THOMSON_DTT759X))
932 goto frontend_detach;
934 break;
935 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
936 case CX88_BOARD_CONEXANT_DVB_T1:
937 case CX88_BOARD_KWORLD_DVB_T_CX22702:
938 case CX88_BOARD_WINFAST_DTV1000:
939 fe0->dvb.frontend = dvb_attach(cx22702_attach,
940 &connexant_refboard_config,
941 &core->i2c_adap);
942 if (fe0->dvb.frontend != NULL) {
943 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
944 0x60, &core->i2c_adap,
945 DVB_PLL_THOMSON_DTT7579))
946 goto frontend_detach;
948 break;
949 case CX88_BOARD_WINFAST_DTV2000H:
950 case CX88_BOARD_WINFAST_DTV2000H_J:
951 case CX88_BOARD_HAUPPAUGE_HVR1100:
952 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
953 case CX88_BOARD_HAUPPAUGE_HVR1300:
954 fe0->dvb.frontend = dvb_attach(cx22702_attach,
955 &hauppauge_hvr_config,
956 &core->i2c_adap);
957 if (fe0->dvb.frontend != NULL) {
958 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
959 &core->i2c_adap, 0x61,
960 TUNER_PHILIPS_FMD1216ME_MK3))
961 goto frontend_detach;
963 break;
964 case CX88_BOARD_HAUPPAUGE_HVR3000:
965 /* MFE frontend 1 */
966 mfe_shared = 1;
967 dev->frontends.gate = 2;
968 /* DVB-S init */
969 fe0->dvb.frontend = dvb_attach(cx24123_attach,
970 &hauppauge_novas_config,
971 &dev->core->i2c_adap);
972 if (fe0->dvb.frontend) {
973 if (!dvb_attach(isl6421_attach,
974 fe0->dvb.frontend,
975 &dev->core->i2c_adap,
976 0x08, ISL6421_DCL, 0x00))
977 goto frontend_detach;
979 /* MFE frontend 2 */
980 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
981 if (!fe1)
982 goto frontend_detach;
983 /* DVB-T init */
984 fe1->dvb.frontend = dvb_attach(cx22702_attach,
985 &hauppauge_hvr_config,
986 &dev->core->i2c_adap);
987 if (fe1->dvb.frontend) {
988 fe1->dvb.frontend->id = 1;
989 if (!dvb_attach(simple_tuner_attach,
990 fe1->dvb.frontend,
991 &dev->core->i2c_adap,
992 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
993 goto frontend_detach;
995 break;
996 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
997 fe0->dvb.frontend = dvb_attach(mt352_attach,
998 &dvico_fusionhdtv,
999 &core->i2c_adap);
1000 if (fe0->dvb.frontend != NULL) {
1001 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1002 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1003 goto frontend_detach;
1004 break;
1006 /* ZL10353 replaces MT352 on later cards */
1007 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1008 &dvico_fusionhdtv_plus_v1_1,
1009 &core->i2c_adap);
1010 if (fe0->dvb.frontend != NULL) {
1011 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1012 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1013 goto frontend_detach;
1015 break;
1016 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1017 /* The tin box says DEE1601, but it seems to be DTT7579
1018 * compatible, with a slightly different MT352 AGC gain. */
1019 fe0->dvb.frontend = dvb_attach(mt352_attach,
1020 &dvico_fusionhdtv_dual,
1021 &core->i2c_adap);
1022 if (fe0->dvb.frontend != NULL) {
1023 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1024 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1025 goto frontend_detach;
1026 break;
1028 /* ZL10353 replaces MT352 on later cards */
1029 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1030 &dvico_fusionhdtv_plus_v1_1,
1031 &core->i2c_adap);
1032 if (fe0->dvb.frontend != NULL) {
1033 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1034 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1035 goto frontend_detach;
1037 break;
1038 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
1039 fe0->dvb.frontend = dvb_attach(mt352_attach,
1040 &dvico_fusionhdtv,
1041 &core->i2c_adap);
1042 if (fe0->dvb.frontend != NULL) {
1043 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1044 0x61, NULL, DVB_PLL_LG_Z201))
1045 goto frontend_detach;
1047 break;
1048 case CX88_BOARD_KWORLD_DVB_T:
1049 case CX88_BOARD_DNTV_LIVE_DVB_T:
1050 case CX88_BOARD_ADSTECH_DVB_T_PCI:
1051 fe0->dvb.frontend = dvb_attach(mt352_attach,
1052 &dntv_live_dvbt_config,
1053 &core->i2c_adap);
1054 if (fe0->dvb.frontend != NULL) {
1055 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1056 0x61, NULL, DVB_PLL_UNKNOWN_1))
1057 goto frontend_detach;
1059 break;
1060 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
1061 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
1062 /* MT352 is on a secondary I2C bus made from some GPIO lines */
1063 fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
1064 &dev->vp3054->adap);
1065 if (fe0->dvb.frontend != NULL) {
1066 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1067 &core->i2c_adap, 0x61,
1068 TUNER_PHILIPS_FMD1216ME_MK3))
1069 goto frontend_detach;
1071 #else
1072 printk(KERN_ERR "%s/2: built without vp3054 support\n",
1073 core->name);
1074 #endif
1075 break;
1076 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
1077 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1078 &dvico_fusionhdtv_hybrid,
1079 &core->i2c_adap);
1080 if (fe0->dvb.frontend != NULL) {
1081 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1082 &core->i2c_adap, 0x61,
1083 TUNER_THOMSON_FE6600))
1084 goto frontend_detach;
1086 break;
1087 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
1088 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1089 &dvico_fusionhdtv_xc3028,
1090 &core->i2c_adap);
1091 if (fe0->dvb.frontend == NULL)
1092 fe0->dvb.frontend = dvb_attach(mt352_attach,
1093 &dvico_fusionhdtv_mt352_xc3028,
1094 &core->i2c_adap);
1096 * On this board, the demod provides the I2C bus pullup.
1097 * We must not permit gate_ctrl to be performed, or
1098 * the xc3028 cannot communicate on the bus.
1100 if (fe0->dvb.frontend)
1101 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1102 if (attach_xc3028(0x61, dev) < 0)
1103 goto frontend_detach;
1104 break;
1105 case CX88_BOARD_PCHDTV_HD3000:
1106 fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
1107 &core->i2c_adap);
1108 if (fe0->dvb.frontend != NULL) {
1109 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1110 &core->i2c_adap, 0x61,
1111 TUNER_THOMSON_DTT761X))
1112 goto frontend_detach;
1114 break;
1115 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
1116 dev->ts_gen_cntrl = 0x08;
1118 /* Do a hardware reset of chip before using it. */
1119 cx_clear(MO_GP0_IO, 1);
1120 mdelay(100);
1121 cx_set(MO_GP0_IO, 1);
1122 mdelay(200);
1124 /* Select RF connector callback */
1125 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
1126 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1127 &fusionhdtv_3_gold,
1128 &core->i2c_adap);
1129 if (fe0->dvb.frontend != NULL) {
1130 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1131 &core->i2c_adap, 0x61,
1132 TUNER_MICROTUNE_4042FI5))
1133 goto frontend_detach;
1135 break;
1136 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
1137 dev->ts_gen_cntrl = 0x08;
1139 /* Do a hardware reset of chip before using it. */
1140 cx_clear(MO_GP0_IO, 1);
1141 mdelay(100);
1142 cx_set(MO_GP0_IO, 9);
1143 mdelay(200);
1144 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1145 &fusionhdtv_3_gold,
1146 &core->i2c_adap);
1147 if (fe0->dvb.frontend != NULL) {
1148 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1149 &core->i2c_adap, 0x61,
1150 TUNER_THOMSON_DTT761X))
1151 goto frontend_detach;
1153 break;
1154 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
1155 dev->ts_gen_cntrl = 0x08;
1157 /* Do a hardware reset of chip before using it. */
1158 cx_clear(MO_GP0_IO, 1);
1159 mdelay(100);
1160 cx_set(MO_GP0_IO, 1);
1161 mdelay(200);
1162 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1163 &fusionhdtv_5_gold,
1164 &core->i2c_adap);
1165 if (fe0->dvb.frontend != NULL) {
1166 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1167 &core->i2c_adap, 0x61,
1168 TUNER_LG_TDVS_H06XF))
1169 goto frontend_detach;
1170 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1171 &core->i2c_adap, 0x43))
1172 goto frontend_detach;
1174 break;
1175 case CX88_BOARD_PCHDTV_HD5500:
1176 dev->ts_gen_cntrl = 0x08;
1178 /* Do a hardware reset of chip before using it. */
1179 cx_clear(MO_GP0_IO, 1);
1180 mdelay(100);
1181 cx_set(MO_GP0_IO, 1);
1182 mdelay(200);
1183 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1184 &pchdtv_hd5500,
1185 &core->i2c_adap);
1186 if (fe0->dvb.frontend != NULL) {
1187 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1188 &core->i2c_adap, 0x61,
1189 TUNER_LG_TDVS_H06XF))
1190 goto frontend_detach;
1191 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1192 &core->i2c_adap, 0x43))
1193 goto frontend_detach;
1195 break;
1196 case CX88_BOARD_ATI_HDTVWONDER:
1197 fe0->dvb.frontend = dvb_attach(nxt200x_attach,
1198 &ati_hdtvwonder,
1199 &core->i2c_adap);
1200 if (fe0->dvb.frontend != NULL) {
1201 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1202 &core->i2c_adap, 0x61,
1203 TUNER_PHILIPS_TUV1236D))
1204 goto frontend_detach;
1206 break;
1207 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
1208 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
1209 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1210 &hauppauge_novas_config,
1211 &core->i2c_adap);
1212 if (fe0->dvb.frontend) {
1213 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
1214 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
1215 goto frontend_detach;
1217 break;
1218 case CX88_BOARD_KWORLD_DVBS_100:
1219 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1220 &kworld_dvbs_100_config,
1221 &core->i2c_adap);
1222 if (fe0->dvb.frontend) {
1223 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1224 fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
1226 break;
1227 case CX88_BOARD_GENIATECH_DVBS:
1228 fe0->dvb.frontend = dvb_attach(cx24123_attach,
1229 &geniatech_dvbs_config,
1230 &core->i2c_adap);
1231 if (fe0->dvb.frontend) {
1232 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1233 fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
1235 break;
1236 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
1237 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1238 &pinnacle_pctv_hd_800i_config,
1239 &core->i2c_adap);
1240 if (fe0->dvb.frontend != NULL) {
1241 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1242 &core->i2c_adap,
1243 &pinnacle_pctv_hd_800i_tuner_config))
1244 goto frontend_detach;
1246 break;
1247 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
1248 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1249 &dvico_hdtv5_pci_nano_config,
1250 &core->i2c_adap);
1251 if (fe0->dvb.frontend != NULL) {
1252 struct dvb_frontend *fe;
1253 struct xc2028_config cfg = {
1254 .i2c_adap = &core->i2c_adap,
1255 .i2c_addr = 0x61,
1257 static struct xc2028_ctrl ctl = {
1258 .fname = XC2028_DEFAULT_FIRMWARE,
1259 .max_len = 64,
1260 .scode_table = XC3028_FE_OREN538,
1263 fe = dvb_attach(xc2028_attach,
1264 fe0->dvb.frontend, &cfg);
1265 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1266 fe->ops.tuner_ops.set_config(fe, &ctl);
1268 break;
1269 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
1270 case CX88_BOARD_WINFAST_DTV1800H:
1271 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1272 &cx88_pinnacle_hybrid_pctv,
1273 &core->i2c_adap);
1274 if (fe0->dvb.frontend) {
1275 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1276 if (attach_xc3028(0x61, dev) < 0)
1277 goto frontend_detach;
1279 break;
1280 case CX88_BOARD_GENIATECH_X8000_MT:
1281 dev->ts_gen_cntrl = 0x00;
1283 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1284 &cx88_geniatech_x8000_mt,
1285 &core->i2c_adap);
1286 if (attach_xc3028(0x61, dev) < 0)
1287 goto frontend_detach;
1288 break;
1289 case CX88_BOARD_KWORLD_ATSC_120:
1290 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1291 &kworld_atsc_120_config,
1292 &core->i2c_adap);
1293 if (attach_xc3028(0x61, dev) < 0)
1294 goto frontend_detach;
1295 break;
1296 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
1297 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1298 &dvico_fusionhdtv7_config,
1299 &core->i2c_adap);
1300 if (fe0->dvb.frontend != NULL) {
1301 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1302 &core->i2c_adap,
1303 &dvico_fusionhdtv7_tuner_config))
1304 goto frontend_detach;
1306 break;
1307 case CX88_BOARD_HAUPPAUGE_HVR4000:
1308 /* MFE frontend 1 */
1309 mfe_shared = 1;
1310 dev->frontends.gate = 2;
1311 /* DVB-S/S2 Init */
1312 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1313 &hauppauge_hvr4000_config,
1314 &dev->core->i2c_adap);
1315 if (fe0->dvb.frontend) {
1316 if (!dvb_attach(isl6421_attach,
1317 fe0->dvb.frontend,
1318 &dev->core->i2c_adap,
1319 0x08, ISL6421_DCL, 0x00))
1320 goto frontend_detach;
1322 /* MFE frontend 2 */
1323 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1324 if (!fe1)
1325 goto frontend_detach;
1326 /* DVB-T Init */
1327 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1328 &hauppauge_hvr_config,
1329 &dev->core->i2c_adap);
1330 if (fe1->dvb.frontend) {
1331 fe1->dvb.frontend->id = 1;
1332 if (!dvb_attach(simple_tuner_attach,
1333 fe1->dvb.frontend,
1334 &dev->core->i2c_adap,
1335 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1336 goto frontend_detach;
1338 break;
1339 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
1340 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1341 &hauppauge_hvr4000_config,
1342 &dev->core->i2c_adap);
1343 if (fe0->dvb.frontend) {
1344 if (!dvb_attach(isl6421_attach,
1345 fe0->dvb.frontend,
1346 &dev->core->i2c_adap,
1347 0x08, ISL6421_DCL, 0x00))
1348 goto frontend_detach;
1350 break;
1351 case CX88_BOARD_PROF_6200:
1352 case CX88_BOARD_TBS_8910:
1353 case CX88_BOARD_TEVII_S420:
1354 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1355 &tevii_tuner_sharp_config,
1356 &core->i2c_adap);
1357 if (fe0->dvb.frontend != NULL) {
1358 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
1359 &core->i2c_adap, DVB_PLL_OPERA1))
1360 goto frontend_detach;
1361 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1362 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1364 } else {
1365 fe0->dvb.frontend = dvb_attach(stv0288_attach,
1366 &tevii_tuner_earda_config,
1367 &core->i2c_adap);
1368 if (fe0->dvb.frontend != NULL) {
1369 if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
1370 &core->i2c_adap))
1371 goto frontend_detach;
1372 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1373 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1376 break;
1377 case CX88_BOARD_TEVII_S460:
1378 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1379 &tevii_s460_config,
1380 &core->i2c_adap);
1381 if (fe0->dvb.frontend != NULL)
1382 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1383 break;
1384 case CX88_BOARD_OMICOM_SS4_PCI:
1385 case CX88_BOARD_TBS_8920:
1386 case CX88_BOARD_PROF_7300:
1387 case CX88_BOARD_SATTRADE_ST4200:
1388 fe0->dvb.frontend = dvb_attach(cx24116_attach,
1389 &hauppauge_hvr4000_config,
1390 &core->i2c_adap);
1391 if (fe0->dvb.frontend != NULL)
1392 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1393 break;
1394 case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
1395 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1396 &cx88_terratec_cinergy_ht_pci_mkii_config,
1397 &core->i2c_adap);
1398 if (fe0->dvb.frontend) {
1399 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1400 if (attach_xc3028(0x61, dev) < 0)
1401 goto frontend_detach;
1403 break;
1404 case CX88_BOARD_PROF_7301:{
1405 struct dvb_tuner_ops *tuner_ops = NULL;
1407 fe0->dvb.frontend = dvb_attach(stv0900_attach,
1408 &prof_7301_stv0900_config,
1409 &core->i2c_adap, 0);
1410 if (fe0->dvb.frontend != NULL) {
1411 if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
1412 &prof_7301_stb6100_config,
1413 &core->i2c_adap))
1414 goto frontend_detach;
1416 tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
1417 tuner_ops->set_frequency = stb6100_set_freq;
1418 tuner_ops->get_frequency = stb6100_get_freq;
1419 tuner_ops->set_bandwidth = stb6100_set_bandw;
1420 tuner_ops->get_bandwidth = stb6100_get_bandw;
1422 core->prev_set_voltage =
1423 fe0->dvb.frontend->ops.set_voltage;
1424 fe0->dvb.frontend->ops.set_voltage =
1425 tevii_dvbs_set_voltage;
1427 break;
1429 case CX88_BOARD_SAMSUNG_SMT_7020:
1430 dev->ts_gen_cntrl = 0x08;
1432 cx_set(MO_GP0_IO, 0x0101);
1434 cx_clear(MO_GP0_IO, 0x01);
1435 mdelay(100);
1436 cx_set(MO_GP0_IO, 0x01);
1437 mdelay(200);
1439 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1440 &samsung_stv0299_config,
1441 &dev->core->i2c_adap);
1442 if (fe0->dvb.frontend) {
1443 fe0->dvb.frontend->ops.tuner_ops.set_params =
1444 samsung_smt_7020_tuner_set_params;
1445 fe0->dvb.frontend->tuner_priv =
1446 &dev->core->i2c_adap;
1447 fe0->dvb.frontend->ops.set_voltage =
1448 samsung_smt_7020_set_voltage;
1449 fe0->dvb.frontend->ops.set_tone =
1450 samsung_smt_7020_set_tone;
1453 break;
1454 case CX88_BOARD_TWINHAN_VP1027_DVBS:
1455 dev->ts_gen_cntrl = 0x00;
1456 fe0->dvb.frontend = dvb_attach(mb86a16_attach,
1457 &twinhan_vp1027,
1458 &core->i2c_adap);
1459 if (fe0->dvb.frontend) {
1460 core->prev_set_voltage =
1461 fe0->dvb.frontend->ops.set_voltage;
1462 fe0->dvb.frontend->ops.set_voltage =
1463 vp1027_set_voltage;
1465 break;
1467 default:
1468 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1469 core->name);
1470 break;
1473 if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
1474 printk(KERN_ERR
1475 "%s/2: frontend initialization failed\n",
1476 core->name);
1477 goto frontend_detach;
1479 /* define general-purpose callback pointer */
1480 fe0->dvb.frontend->callback = cx88_tuner_callback;
1482 /* Ensure all frontends negotiate bus access */
1483 fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1484 if (fe1)
1485 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1487 /* Put the analog decoder in standby to keep it quiet */
1488 call_all(core, core, s_power, 0);
1490 /* register everything */
1491 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1492 &dev->pci->dev, adapter_nr, mfe_shared, NULL);
1494 frontend_detach:
1495 core->gate_ctrl = NULL;
1496 videobuf_dvb_dealloc_frontends(&dev->frontends);
1497 return -EINVAL;
1500 /* ----------------------------------------------------------- */
1502 /* CX8802 MPEG -> mini driver - We have been given the hardware */
1503 static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
1505 struct cx88_core *core = drv->core;
1506 int err = 0;
1507 dprintk( 1, "%s\n", __func__);
1509 switch (core->boardnr) {
1510 case CX88_BOARD_HAUPPAUGE_HVR1300:
1511 /* We arrive here with either the cx23416 or the cx22702
1512 * on the bus. Take the bus from the cx23416 and enable the
1513 * cx22702 demod
1515 /* Toggle reset on cx22702 leaving i2c active */
1516 cx_set(MO_GP0_IO, 0x00000080);
1517 udelay(1000);
1518 cx_clear(MO_GP0_IO, 0x00000080);
1519 udelay(50);
1520 cx_set(MO_GP0_IO, 0x00000080);
1521 udelay(1000);
1522 /* enable the cx22702 pins */
1523 cx_clear(MO_GP0_IO, 0x00000004);
1524 udelay(1000);
1525 break;
1527 case CX88_BOARD_HAUPPAUGE_HVR3000:
1528 case CX88_BOARD_HAUPPAUGE_HVR4000:
1529 /* Toggle reset on cx22702 leaving i2c active */
1530 cx_set(MO_GP0_IO, 0x00000080);
1531 udelay(1000);
1532 cx_clear(MO_GP0_IO, 0x00000080);
1533 udelay(50);
1534 cx_set(MO_GP0_IO, 0x00000080);
1535 udelay(1000);
1536 switch (core->dvbdev->frontends.active_fe_id) {
1537 case 1: /* DVB-S/S2 Enabled */
1538 /* tri-state the cx22702 pins */
1539 cx_set(MO_GP0_IO, 0x00000004);
1540 /* Take the cx24116/cx24123 out of reset */
1541 cx_write(MO_SRST_IO, 1);
1542 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1543 break;
1544 case 2: /* DVB-T Enabled */
1545 /* Put the cx24116/cx24123 into reset */
1546 cx_write(MO_SRST_IO, 0);
1547 /* enable the cx22702 pins */
1548 cx_clear(MO_GP0_IO, 0x00000004);
1549 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1550 break;
1552 udelay(1000);
1553 break;
1555 default:
1556 err = -ENODEV;
1558 return err;
1561 /* CX8802 MPEG -> mini driver - We no longer have the hardware */
1562 static int cx8802_dvb_advise_release(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 /* Do Nothing, leave the cx22702 on the bus. */
1571 break;
1572 case CX88_BOARD_HAUPPAUGE_HVR3000:
1573 case CX88_BOARD_HAUPPAUGE_HVR4000:
1574 break;
1575 default:
1576 err = -ENODEV;
1578 return err;
1581 static int cx8802_dvb_probe(struct cx8802_driver *drv)
1583 struct cx88_core *core = drv->core;
1584 struct cx8802_dev *dev = drv->core->dvbdev;
1585 int err;
1586 struct videobuf_dvb_frontend *fe;
1587 int i;
1589 dprintk( 1, "%s\n", __func__);
1590 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1591 core->boardnr,
1592 core->name,
1593 core->pci_bus,
1594 core->pci_slot);
1596 err = -ENODEV;
1597 if (!(core->board.mpeg & CX88_MPEG_DVB))
1598 goto fail_core;
1600 /* If vp3054 isn't enabled, a stub will just return 0 */
1601 err = vp3054_i2c_probe(dev);
1602 if (0 != err)
1603 goto fail_core;
1605 /* dvb stuff */
1606 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1607 dev->ts_gen_cntrl = 0x0c;
1609 err = cx8802_alloc_frontends(dev);
1610 if (err)
1611 goto fail_core;
1613 err = -ENODEV;
1614 for (i = 1; i <= core->board.num_frontends; i++) {
1615 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
1616 if (fe == NULL) {
1617 printk(KERN_ERR "%s() failed to get frontend(%d)\n",
1618 __func__, i);
1619 goto fail_probe;
1621 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
1622 &dev->pci->dev, &dev->slock,
1623 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1624 V4L2_FIELD_TOP,
1625 sizeof(struct cx88_buffer),
1626 dev, NULL);
1627 /* init struct videobuf_dvb */
1628 fe->dvb.name = dev->core->name;
1631 err = dvb_register(dev);
1632 if (err)
1633 /* frontends/adapter de-allocated in dvb_register */
1634 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
1635 core->name, err);
1636 return err;
1637 fail_probe:
1638 videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends);
1639 fail_core:
1640 return err;
1643 static int cx8802_dvb_remove(struct cx8802_driver *drv)
1645 struct cx88_core *core = drv->core;
1646 struct cx8802_dev *dev = drv->core->dvbdev;
1648 dprintk( 1, "%s\n", __func__);
1650 videobuf_dvb_unregister_bus(&dev->frontends);
1652 vp3054_i2c_remove(dev);
1654 core->gate_ctrl = NULL;
1656 return 0;
1659 static struct cx8802_driver cx8802_dvb_driver = {
1660 .type_id = CX88_MPEG_DVB,
1661 .hw_access = CX8802_DRVCTL_SHARED,
1662 .probe = cx8802_dvb_probe,
1663 .remove = cx8802_dvb_remove,
1664 .advise_acquire = cx8802_dvb_advise_acquire,
1665 .advise_release = cx8802_dvb_advise_release,
1668 static int __init dvb_init(void)
1670 printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n",
1671 (CX88_VERSION_CODE >> 16) & 0xff,
1672 (CX88_VERSION_CODE >> 8) & 0xff,
1673 CX88_VERSION_CODE & 0xff);
1674 #ifdef SNAPSHOT
1675 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
1676 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1677 #endif
1678 return cx8802_register_driver(&cx8802_dvb_driver);
1681 static void __exit dvb_fini(void)
1683 cx8802_unregister_driver(&cx8802_dvb_driver);
1686 module_init(dvb_init);
1687 module_exit(dvb_fini);
1690 * Local variables:
1691 * c-basic-offset: 8
1692 * compile-command: "make DVB=1"
1693 * End: