1/*
2 *
3 * device driver for Conexant 2388x based TV cards
4 * MPEG Transport Stream (DVB) routines
5 *
6 * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 *
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.
13 *
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.
18 *
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.
22 */
23
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>
31
32#include "cx88.h"
33#include "dvb-pll.h"
34#include <media/v4l2-common.h>
35
36#include "mt352.h"
37#include "mt352_priv.h"
38#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
39# include "cx88-vp3054-i2c.h"
40#endif
41#include "zl10353.h"
42#include "cx22702.h"
43#include "or51132.h"
44#include "lgdt330x.h"
45#include "nxt200x.h"
46#include "cx24123.h"
47#include "isl6421.h"
48
49MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
50MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
51MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
52MODULE_LICENSE("GPL");
53
54static unsigned int debug = 0;
55module_param(debug, int, 0644);
56MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
57
58#define dprintk(level,fmt, arg...)	if (debug >= level) \
59	printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
60
61/* ------------------------------------------------------------------ */
62
63static int dvb_buf_setup(struct videobuf_queue *q,
64			 unsigned int *count, unsigned int *size)
65{
66	struct cx8802_dev *dev = q->priv_data;
67
68	dev->ts_packet_size  = 188 * 4;
69	dev->ts_packet_count = 32;
70
71	*size  = dev->ts_packet_size * dev->ts_packet_count;
72	*count = 32;
73	return 0;
74}
75
76static int dvb_buf_prepare(struct videobuf_queue *q,
77			   struct videobuf_buffer *vb, enum v4l2_field field)
78{
79	struct cx8802_dev *dev = q->priv_data;
80	return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
81}
82
83static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
84{
85	struct cx8802_dev *dev = q->priv_data;
86	cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
87}
88
89static void dvb_buf_release(struct videobuf_queue *q,
90			    struct videobuf_buffer *vb)
91{
92	cx88_free_buffer(q, (struct cx88_buffer*)vb);
93}
94
95static struct videobuf_queue_ops dvb_qops = {
96	.buf_setup    = dvb_buf_setup,
97	.buf_prepare  = dvb_buf_prepare,
98	.buf_queue    = dvb_buf_queue,
99	.buf_release  = dvb_buf_release,
100};
101
102/* ------------------------------------------------------------------ */
103
104static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
105{
106	struct cx8802_dev *dev= fe->dvb->priv;
107	struct cx8802_driver *drv = NULL;
108	int ret = 0;
109
110	drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
111	if (drv) {
112		if (acquire)
113			ret = drv->request_acquire(drv);
114		else
115			ret = drv->request_release(drv);
116	}
117
118	return ret;
119}
120
121/* ------------------------------------------------------------------ */
122
123static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
124{
125	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x39 };
126	static u8 reset []         = { RESET,      0x80 };
127	static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
128	static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
129	static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
130	static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
131
132	mt352_write(fe, clock_config,   sizeof(clock_config));
133	udelay(200);
134	mt352_write(fe, reset,          sizeof(reset));
135	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
136
137	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
138	mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
139	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
140	return 0;
141}
142
143static int dvico_dual_demod_init(struct dvb_frontend *fe)
144{
145	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x38 };
146	static u8 reset []         = { RESET,      0x80 };
147	static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
148	static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
149	static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
150	static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
151
152	mt352_write(fe, clock_config,   sizeof(clock_config));
153	udelay(200);
154	mt352_write(fe, reset,          sizeof(reset));
155	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
156
157	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
158	mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
159	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
160
161	return 0;
162}
163
164static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
165{
166	static u8 clock_config []  = { 0x89, 0x38, 0x39 };
167	static u8 reset []         = { 0x50, 0x80 };
168	static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
169	static u8 agc_cfg []       = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
170				       0x00, 0xFF, 0x00, 0x40, 0x40 };
171	static u8 dntv_extra[]     = { 0xB5, 0x7A };
172	static u8 capt_range_cfg[] = { 0x75, 0x32 };
173
174	mt352_write(fe, clock_config,   sizeof(clock_config));
175	udelay(2000);
176	mt352_write(fe, reset,          sizeof(reset));
177	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
178
179	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
180	udelay(2000);
181	mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
182	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
183
184	return 0;
185}
186
187static struct mt352_config dvico_fusionhdtv = {
188	.demod_address = 0x0f,
189	.demod_init    = dvico_fusionhdtv_demod_init,
190};
191
192static struct mt352_config dntv_live_dvbt_config = {
193	.demod_address = 0x0f,
194	.demod_init    = dntv_live_dvbt_demod_init,
195};
196
197static struct mt352_config dvico_fusionhdtv_dual = {
198	.demod_address = 0x0f,
199	.demod_init    = dvico_dual_demod_init,
200};
201
202#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
203static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
204{
205	static u8 clock_config []  = { 0x89, 0x38, 0x38 };
206	static u8 reset []         = { 0x50, 0x80 };
207	static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
208	static u8 agc_cfg []       = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
209				       0x00, 0xFF, 0x00, 0x40, 0x40 };
210	static u8 dntv_extra[]     = { 0xB5, 0x7A };
211	static u8 capt_range_cfg[] = { 0x75, 0x32 };
212
213	mt352_write(fe, clock_config,   sizeof(clock_config));
214	udelay(2000);
215	mt352_write(fe, reset,          sizeof(reset));
216	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
217
218	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
219	udelay(2000);
220	mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
221	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
222
223	return 0;
224}
225
226static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
227{
228	struct cx8802_dev *dev= fe->dvb->priv;
229
230	/* this message is to set up ATC and ALC */
231	static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
232	struct i2c_msg msg =
233		{ .addr = dev->core->pll_addr, .flags = 0,
234		  .buf = fmd1216_init, .len = sizeof(fmd1216_init) };
235	int err;
236
237	if (fe->ops.i2c_gate_ctrl)
238		fe->ops.i2c_gate_ctrl(fe, 1);
239	if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
240		if (err < 0)
241			return err;
242		else
243			return -EREMOTEIO;
244	}
245
246	return 0;
247}
248
249static int dntv_live_dvbt_pro_tuner_set_params(struct dvb_frontend* fe,
250					       struct dvb_frontend_parameters* params)
251{
252	struct cx8802_dev *dev= fe->dvb->priv;
253	u8 buf[4];
254	struct i2c_msg msg =
255		{ .addr = dev->core->pll_addr, .flags = 0,
256		  .buf = buf, .len = 4 };
257	int err;
258
259	/* Switch PLL to DVB mode */
260	err = philips_fmd1216_pll_init(fe);
261	if (err)
262		return err;
263
264	/* Tune PLL */
265	dvb_pll_configure(dev->core->pll_desc, buf,
266			  params->frequency,
267			  params->u.ofdm.bandwidth);
268	if (fe->ops.i2c_gate_ctrl)
269		fe->ops.i2c_gate_ctrl(fe, 1);
270	if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
271
272		printk(KERN_WARNING "cx88-dvb: %s error "
273		       "(addr %02x <- %02x, err = %i)\n",
274		       __FUNCTION__, dev->core->pll_addr, buf[0], err);
275		if (err < 0)
276			return err;
277		else
278			return -EREMOTEIO;
279	}
280
281	return 0;
282}
283
284static struct mt352_config dntv_live_dvbt_pro_config = {
285	.demod_address = 0x0f,
286	.no_tuner      = 1,
287	.demod_init    = dntv_live_dvbt_pro_demod_init,
288};
289#endif
290
291static struct zl10353_config dvico_fusionhdtv_hybrid = {
292	.demod_address = 0x0f,
293	.no_tuner      = 1,
294};
295
296static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
297	.demod_address = 0x0f,
298};
299
300static struct cx22702_config connexant_refboard_config = {
301	.demod_address = 0x43,
302	.output_mode   = CX22702_SERIAL_OUTPUT,
303};
304
305static struct cx22702_config hauppauge_hvr_config = {
306	.demod_address = 0x63,
307	.output_mode   = CX22702_SERIAL_OUTPUT,
308};
309
310static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
311{
312	struct cx8802_dev *dev= fe->dvb->priv;
313	dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
314	return 0;
315}
316
317static struct or51132_config pchdtv_hd3000 = {
318	.demod_address = 0x15,
319	.set_ts_params = or51132_set_ts_param,
320};
321
322static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
323{
324	struct cx8802_dev *dev= fe->dvb->priv;
325	struct cx88_core *core = dev->core;
326
327	dprintk(1, "%s: index = %d\n", __FUNCTION__, index);
328	if (index == 0)
329		cx_clear(MO_GP0_IO, 8);
330	else
331		cx_set(MO_GP0_IO, 8);
332	return 0;
333}
334
335static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
336{
337	struct cx8802_dev *dev= fe->dvb->priv;
338	if (is_punctured)
339		dev->ts_gen_cntrl |= 0x04;
340	else
341		dev->ts_gen_cntrl &= ~0x04;
342	return 0;
343}
344
345static struct lgdt330x_config fusionhdtv_3_gold = {
346	.demod_address = 0x0e,
347	.demod_chip    = LGDT3302,
348	.serial_mpeg   = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
349	.set_ts_params = lgdt330x_set_ts_param,
350};
351
352static struct lgdt330x_config fusionhdtv_5_gold = {
353	.demod_address = 0x0e,
354	.demod_chip    = LGDT3303,
355	.serial_mpeg   = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
356	.set_ts_params = lgdt330x_set_ts_param,
357};
358
359static struct lgdt330x_config pchdtv_hd5500 = {
360	.demod_address = 0x59,
361	.demod_chip    = LGDT3303,
362	.serial_mpeg   = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
363	.set_ts_params = lgdt330x_set_ts_param,
364};
365
366static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
367{
368	struct cx8802_dev *dev= fe->dvb->priv;
369	dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
370	return 0;
371}
372
373static int nxt200x_set_pll_input(u8* buf, int input)
374{
375	if (input)
376		buf[3] |= 0x08;
377	else
378		buf[3] &= ~0x08;
379	return 0;
380}
381
382static struct nxt200x_config ati_hdtvwonder = {
383	.demod_address = 0x0a,
384	.set_pll_input = nxt200x_set_pll_input,
385	.set_ts_params = nxt200x_set_ts_param,
386};
387
388static int cx24123_set_ts_param(struct dvb_frontend* fe,
389	int is_punctured)
390{
391	struct cx8802_dev *dev= fe->dvb->priv;
392	dev->ts_gen_cntrl = 0x02;
393	return 0;
394}
395
396static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
397				       fe_sec_voltage_t voltage)
398{
399	struct cx8802_dev *dev= fe->dvb->priv;
400	struct cx88_core *core = dev->core;
401
402	if (voltage == SEC_VOLTAGE_OFF)
403		cx_write(MO_GP0_IO, 0x000006fb);
404	else
405		cx_write(MO_GP0_IO, 0x000006f9);
406
407	if (core->prev_set_voltage)
408		return core->prev_set_voltage(fe, voltage);
409	return 0;
410}
411
412static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
413				      fe_sec_voltage_t voltage)
414{
415	struct cx8802_dev *dev= fe->dvb->priv;
416	struct cx88_core *core = dev->core;
417
418	if (voltage == SEC_VOLTAGE_OFF) {
419		dprintk(1,"LNB Voltage OFF\n");
420		cx_write(MO_GP0_IO, 0x0000efff);
421	}
422
423	if (core->prev_set_voltage)
424		return core->prev_set_voltage(fe, voltage);
425	return 0;
426}
427
428static struct cx24123_config geniatech_dvbs_config = {
429	.demod_address = 0x55,
430	.set_ts_params = cx24123_set_ts_param,
431};
432
433static struct cx24123_config hauppauge_novas_config = {
434	.demod_address = 0x55,
435	.set_ts_params = cx24123_set_ts_param,
436};
437
438static struct cx24123_config kworld_dvbs_100_config = {
439	.demod_address = 0x15,
440	.set_ts_params = cx24123_set_ts_param,
441	.lnb_polarity  = 1,
442};
443
444static int dvb_register(struct cx8802_dev *dev)
445{
446	/* init struct videobuf_dvb */
447	dev->dvb.name = dev->core->name;
448	dev->ts_gen_cntrl = 0x0c;
449
450	/* init frontend */
451	switch (dev->core->board) {
452	case CX88_BOARD_HAUPPAUGE_DVB_T1:
453		dev->dvb.frontend = dvb_attach(cx22702_attach,
454					       &connexant_refboard_config,
455					       &dev->core->i2c_adap);
456		if (dev->dvb.frontend != NULL) {
457			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
458				   &dev->core->i2c_adap,
459				   &dvb_pll_thomson_dtt759x);
460		}
461		break;
462	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
463	case CX88_BOARD_CONEXANT_DVB_T1:
464	case CX88_BOARD_KWORLD_DVB_T_CX22702:
465	case CX88_BOARD_WINFAST_DTV1000:
466		dev->dvb.frontend = dvb_attach(cx22702_attach,
467					       &connexant_refboard_config,
468					       &dev->core->i2c_adap);
469		if (dev->dvb.frontend != NULL) {
470			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
471				   &dev->core->i2c_adap,
472				   &dvb_pll_thomson_dtt7579);
473		}
474		break;
475	case CX88_BOARD_WINFAST_DTV2000H:
476	case CX88_BOARD_HAUPPAUGE_HVR1100:
477	case CX88_BOARD_HAUPPAUGE_HVR1100LP:
478	case CX88_BOARD_HAUPPAUGE_HVR1300:
479	case CX88_BOARD_HAUPPAUGE_HVR3000:
480		dev->dvb.frontend = dvb_attach(cx22702_attach,
481					       &hauppauge_hvr_config,
482					       &dev->core->i2c_adap);
483		if (dev->dvb.frontend != NULL) {
484			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
485				   &dev->core->i2c_adap, &dvb_pll_fmd1216me);
486		}
487		break;
488	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
489		dev->dvb.frontend = dvb_attach(mt352_attach,
490					       &dvico_fusionhdtv,
491					       &dev->core->i2c_adap);
492		if (dev->dvb.frontend != NULL) {
493			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
494				   NULL, &dvb_pll_thomson_dtt7579);
495			break;
496		}
497		/* ZL10353 replaces MT352 on later cards */
498		dev->dvb.frontend = dvb_attach(zl10353_attach,
499					       &dvico_fusionhdtv_plus_v1_1,
500					       &dev->core->i2c_adap);
501		if (dev->dvb.frontend != NULL) {
502			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
503				   NULL, &dvb_pll_thomson_dtt7579);
504		}
505		break;
506	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
507		/* The tin box says DEE1601, but it seems to be DTT7579
508		 * compatible, with a slightly different MT352 AGC gain. */
509		dev->dvb.frontend = dvb_attach(mt352_attach,
510					       &dvico_fusionhdtv_dual,
511					       &dev->core->i2c_adap);
512		if (dev->dvb.frontend != NULL) {
513			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
514				   NULL, &dvb_pll_thomson_dtt7579);
515			break;
516		}
517		/* ZL10353 replaces MT352 on later cards */
518		dev->dvb.frontend = dvb_attach(zl10353_attach,
519					       &dvico_fusionhdtv_plus_v1_1,
520					       &dev->core->i2c_adap);
521		if (dev->dvb.frontend != NULL) {
522			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
523				   NULL, &dvb_pll_thomson_dtt7579);
524		}
525		break;
526	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
527		dev->dvb.frontend = dvb_attach(mt352_attach,
528					       &dvico_fusionhdtv,
529					       &dev->core->i2c_adap);
530		if (dev->dvb.frontend != NULL) {
531			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
532				   NULL, &dvb_pll_lg_z201);
533		}
534		break;
535	case CX88_BOARD_KWORLD_DVB_T:
536	case CX88_BOARD_DNTV_LIVE_DVB_T:
537	case CX88_BOARD_ADSTECH_DVB_T_PCI:
538		dev->dvb.frontend = dvb_attach(mt352_attach,
539					       &dntv_live_dvbt_config,
540					       &dev->core->i2c_adap);
541		if (dev->dvb.frontend != NULL) {
542			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
543				   NULL, &dvb_pll_unknown_1);
544		}
545		break;
546	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
547#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
548		dev->core->pll_addr = 0x61;
549		dev->core->pll_desc = &dvb_pll_fmd1216me;
550		dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
551			&((struct vp3054_i2c_state *)dev->card_priv)->adap);
552		if (dev->dvb.frontend != NULL) {
553			dev->dvb.frontend->ops.tuner_ops.set_params = dntv_live_dvbt_pro_tuner_set_params;
554		}
555#else
556		printk("%s: built without vp3054 support\n", dev->core->name);
557#endif
558		break;
559	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
560		dev->dvb.frontend = dvb_attach(zl10353_attach,
561					       &dvico_fusionhdtv_hybrid,
562					       &dev->core->i2c_adap);
563		if (dev->dvb.frontend != NULL) {
564			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
565				   &dev->core->i2c_adap,
566				   &dvb_pll_thomson_fe6600);
567		}
568		break;
569	case CX88_BOARD_PCHDTV_HD3000:
570		dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
571					       &dev->core->i2c_adap);
572		if (dev->dvb.frontend != NULL) {
573			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
574				   &dev->core->i2c_adap,
575				   &dvb_pll_thomson_dtt761x);
576		}
577		break;
578	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
579		dev->ts_gen_cntrl = 0x08;
580		{
581		/* Do a hardware reset of chip before using it. */
582		struct cx88_core *core = dev->core;
583
584		cx_clear(MO_GP0_IO, 1);
585		mdelay(100);
586		cx_set(MO_GP0_IO, 1);
587		mdelay(200);
588
589		/* Select RF connector callback */
590		fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
591		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
592					       &fusionhdtv_3_gold,
593					       &dev->core->i2c_adap);
594		if (dev->dvb.frontend != NULL) {
595			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
596				   &dev->core->i2c_adap,
597				   &dvb_pll_microtune_4042);
598		}
599		}
600		break;
601	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
602		dev->ts_gen_cntrl = 0x08;
603		{
604		/* Do a hardware reset of chip before using it. */
605		struct cx88_core *core = dev->core;
606
607		cx_clear(MO_GP0_IO, 1);
608		mdelay(100);
609		cx_set(MO_GP0_IO, 9);
610		mdelay(200);
611		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
612					       &fusionhdtv_3_gold,
613					       &dev->core->i2c_adap);
614		if (dev->dvb.frontend != NULL) {
615			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
616				   &dev->core->i2c_adap,
617				   &dvb_pll_thomson_dtt761x);
618		}
619		}
620		break;
621	case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
622		dev->ts_gen_cntrl = 0x08;
623		{
624		/* Do a hardware reset of chip before using it. */
625		struct cx88_core *core = dev->core;
626
627		cx_clear(MO_GP0_IO, 1);
628		mdelay(100);
629		cx_set(MO_GP0_IO, 1);
630		mdelay(200);
631		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
632					       &fusionhdtv_5_gold,
633					       &dev->core->i2c_adap);
634		if (dev->dvb.frontend != NULL) {
635			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
636				   &dev->core->i2c_adap,
637				   &dvb_pll_lg_tdvs_h06xf);
638		}
639		}
640		break;
641	case CX88_BOARD_PCHDTV_HD5500:
642		dev->ts_gen_cntrl = 0x08;
643		{
644		/* Do a hardware reset of chip before using it. */
645		struct cx88_core *core = dev->core;
646
647		cx_clear(MO_GP0_IO, 1);
648		mdelay(100);
649		cx_set(MO_GP0_IO, 1);
650		mdelay(200);
651		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
652					       &pchdtv_hd5500,
653					       &dev->core->i2c_adap);
654		if (dev->dvb.frontend != NULL) {
655			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
656				   &dev->core->i2c_adap,
657				   &dvb_pll_lg_tdvs_h06xf);
658		}
659		}
660		break;
661	case CX88_BOARD_ATI_HDTVWONDER:
662		dev->dvb.frontend = dvb_attach(nxt200x_attach,
663					       &ati_hdtvwonder,
664					       &dev->core->i2c_adap);
665		if (dev->dvb.frontend != NULL) {
666			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
667				   NULL, &dvb_pll_tuv1236d);
668		}
669		break;
670	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
671	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
672		dev->dvb.frontend = dvb_attach(cx24123_attach,
673					       &hauppauge_novas_config,
674					       &dev->core->i2c_adap);
675		if (dev->dvb.frontend) {
676			dvb_attach(isl6421_attach, dev->dvb.frontend,
677				   &dev->core->i2c_adap, 0x08, 0x00, 0x00);
678		}
679		break;
680	case CX88_BOARD_KWORLD_DVBS_100:
681		dev->dvb.frontend = dvb_attach(cx24123_attach,
682					       &kworld_dvbs_100_config,
683					       &dev->core->i2c_adap);
684		if (dev->dvb.frontend) {
685			dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
686			dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
687		}
688		break;
689	case CX88_BOARD_GENIATECH_DVBS:
690		dev->dvb.frontend = dvb_attach(cx24123_attach,
691					       &geniatech_dvbs_config,
692					       &dev->core->i2c_adap);
693		if (dev->dvb.frontend) {
694			dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
695			dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
696		}
697		break;
698	default:
699		printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
700		       dev->core->name);
701		break;
702	}
703	if (NULL == dev->dvb.frontend) {
704		printk("%s: frontend initialization failed\n",dev->core->name);
705		return -1;
706	}
707
708	if (dev->core->pll_desc) {
709		dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min;
710		dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max;
711	}
712	/* Ensure all frontends negotiate bus access */
713	dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
714
715	/* Put the analog decoder in standby to keep it quiet */
716	cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
717
718	/* register everything */
719	return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev);
720}
721
722/* ----------------------------------------------------------- */
723
724/* CX8802 MPEG -> mini driver - We have been given the hardware */
725static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
726{
727	struct cx88_core *core = drv->core;
728	int err = 0;
729	dprintk( 1, "%s\n", __FUNCTION__);
730
731	switch (core->board) {
732	case CX88_BOARD_HAUPPAUGE_HVR1300:
733		/* We arrive here with either the cx23416 or the cx22702
734		 * on the bus. Take the bus from the cx23416 and enable the
735		 * cx22702 demod
736		 */
737		cx_set(MO_GP0_IO,   0x00000080); /* cx22702 out of reset and enable */
738		cx_clear(MO_GP0_IO, 0x00000004);
739		udelay(1000);
740		break;
741	default:
742		err = -ENODEV;
743	}
744	return err;
745}
746
747/* CX8802 MPEG -> mini driver - We no longer have the hardware */
748static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
749{
750	struct cx88_core *core = drv->core;
751	int err = 0;
752	dprintk( 1, "%s\n", __FUNCTION__);
753
754	switch (core->board) {
755	case CX88_BOARD_HAUPPAUGE_HVR1300:
756		/* Do Nothing, leave the cx22702 on the bus. */
757		break;
758	default:
759		err = -ENODEV;
760	}
761	return err;
762}
763
764static int cx8802_dvb_probe(struct cx8802_driver *drv)
765{
766	struct cx88_core *core = drv->core;
767	struct cx8802_dev *dev = drv->core->dvbdev;
768	int err;
769
770	dprintk( 1, "%s\n", __FUNCTION__);
771	dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
772		core->board,
773		core->name,
774		core->pci_bus,
775		core->pci_slot);
776
777	err = -ENODEV;
778	if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB))
779		goto fail_core;
780
781#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
782	err = vp3054_i2c_probe(dev);
783	if (0 != err)
784		goto fail_core;
785#endif
786
787	/* dvb stuff */
788	printk("%s/2: cx2388x based dvb card\n", core->name);
789	videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
790			    dev->pci, &dev->slock,
791			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
792			    V4L2_FIELD_TOP,
793			    sizeof(struct cx88_buffer),
794			    dev);
795	err = dvb_register(dev);
796	if (err != 0)
797		printk("%s dvb_register failed err = %d\n", __FUNCTION__, err);
798
799 fail_core:
800	return err;
801}
802
803static int cx8802_dvb_remove(struct cx8802_driver *drv)
804{
805	struct cx8802_dev *dev = drv->core->dvbdev;
806
807	/* dvb */
808	videobuf_dvb_unregister(&dev->dvb);
809
810#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
811	vp3054_i2c_remove(dev);
812#endif
813
814	return 0;
815}
816
817static struct cx8802_driver cx8802_dvb_driver = {
818	.type_id        = CX88_MPEG_DVB,
819	.hw_access      = CX8802_DRVCTL_SHARED,
820	.probe          = cx8802_dvb_probe,
821	.remove         = cx8802_dvb_remove,
822	.advise_acquire = cx8802_dvb_advise_acquire,
823	.advise_release = cx8802_dvb_advise_release,
824};
825
826static int dvb_init(void)
827{
828	printk(KERN_INFO "cx2388x dvb driver version %d.%d.%d loaded\n",
829	       (CX88_VERSION_CODE >> 16) & 0xff,
830	       (CX88_VERSION_CODE >>  8) & 0xff,
831	       CX88_VERSION_CODE & 0xff);
832#ifdef SNAPSHOT
833	printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
834	       SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
835#endif
836	return cx8802_register_driver(&cx8802_dvb_driver);
837}
838
839static void dvb_fini(void)
840{
841	cx8802_unregister_driver(&cx8802_dvb_driver);
842}
843
844module_init(dvb_init);
845module_exit(dvb_fini);
846
847/*
848 * Local variables:
849 * c-basic-offset: 8
850 * compile-command: "make DVB=1"
851 * End:
852 */
853