cx88-dvb.c 33.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
/*
 *
 * device driver for Conexant 2388x based TV cards
 * MPEG Transport Stream (DVB) routines
 *
6
 * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
L
Linus Torvalds 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/kthread.h>
#include <linux/file.h>
#include <linux/suspend.h>

#include "cx88.h"
#include "dvb-pll.h"
34
#include <media/v4l2-common.h>
M
Mauro Carvalho Chehab 已提交
35

36 37
#include "mt352.h"
#include "mt352_priv.h"
38
#include "cx88-vp3054-i2c.h"
39 40 41 42
#include "zl10353.h"
#include "cx22702.h"
#include "or51132.h"
#include "lgdt330x.h"
43 44
#include "s5h1409.h"
#include "xc5000.h"
45 46
#include "nxt200x.h"
#include "cx24123.h"
47
#include "isl6421.h"
48
#include "tuner-simple.h"
49
#include "tda9887.h"
50
#include "s5h1411.h"
51 52 53 54
#include "stv0299.h"
#include "z0194a.h"
#include "stv0288.h"
#include "stb6000.h"
55
#include "cx24116.h"
L
Linus Torvalds 已提交
56 57 58 59 60 61

MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");

62
static unsigned int debug;
L
Linus Torvalds 已提交
63 64 65
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,"enable debug messages [dvb]");

66 67
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);

L
Linus Torvalds 已提交
68
#define dprintk(level,fmt, arg...)	if (debug >= level) \
69
	printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
L
Linus Torvalds 已提交
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

/* ------------------------------------------------------------------ */

static int dvb_buf_setup(struct videobuf_queue *q,
			 unsigned int *count, unsigned int *size)
{
	struct cx8802_dev *dev = q->priv_data;

	dev->ts_packet_size  = 188 * 4;
	dev->ts_packet_count = 32;

	*size  = dev->ts_packet_size * dev->ts_packet_count;
	*count = 32;
	return 0;
}

86 87
static int dvb_buf_prepare(struct videobuf_queue *q,
			   struct videobuf_buffer *vb, enum v4l2_field field)
L
Linus Torvalds 已提交
88 89
{
	struct cx8802_dev *dev = q->priv_data;
90
	return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
L
Linus Torvalds 已提交
91 92 93 94 95 96 97 98
}

static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
	struct cx8802_dev *dev = q->priv_data;
	cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
}

99 100
static void dvb_buf_release(struct videobuf_queue *q,
			    struct videobuf_buffer *vb)
L
Linus Torvalds 已提交
101
{
102
	cx88_free_buffer(q, (struct cx88_buffer*)vb);
L
Linus Torvalds 已提交
103 104
}

A
Adrian Bunk 已提交
105
static struct videobuf_queue_ops dvb_qops = {
L
Linus Torvalds 已提交
106 107 108 109 110 111 112
	.buf_setup    = dvb_buf_setup,
	.buf_prepare  = dvb_buf_prepare,
	.buf_queue    = dvb_buf_queue,
	.buf_release  = dvb_buf_release,
};

/* ------------------------------------------------------------------ */
113 114 115 116 117 118 119 120 121

static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
{
	struct cx8802_dev *dev= fe->dvb->priv;
	struct cx8802_driver *drv = NULL;
	int ret = 0;

	drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
	if (drv) {
122
		if (acquire)
123 124 125 126 127 128 129 130 131 132
			ret = drv->request_acquire(drv);
		else
			ret = drv->request_release(drv);
	}

	return ret;
}

/* ------------------------------------------------------------------ */

133
static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
L
Linus Torvalds 已提交
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
{
	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x39 };
	static u8 reset []         = { RESET,      0x80 };
	static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
	static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
	static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
	static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };

	mt352_write(fe, clock_config,   sizeof(clock_config));
	udelay(200);
	mt352_write(fe, reset,          sizeof(reset));
	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));

	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
	mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
	return 0;
}

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
static int dvico_dual_demod_init(struct dvb_frontend *fe)
{
	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x38 };
	static u8 reset []         = { RESET,      0x80 };
	static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
	static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
	static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
	static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };

	mt352_write(fe, clock_config,   sizeof(clock_config));
	udelay(200);
	mt352_write(fe, reset,          sizeof(reset));
	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));

	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
	mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));

	return 0;
}

L
Linus Torvalds 已提交
174 175 176 177 178 179
static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
{
	static u8 clock_config []  = { 0x89, 0x38, 0x39 };
	static u8 reset []         = { 0x50, 0x80 };
	static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
	static u8 agc_cfg []       = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
180
				       0x00, 0xFF, 0x00, 0x40, 0x40 };
L
Linus Torvalds 已提交
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
	static u8 dntv_extra[]     = { 0xB5, 0x7A };
	static u8 capt_range_cfg[] = { 0x75, 0x32 };

	mt352_write(fe, clock_config,   sizeof(clock_config));
	udelay(2000);
	mt352_write(fe, reset,          sizeof(reset));
	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));

	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
	udelay(2000);
	mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));

	return 0;
}

static struct mt352_config dvico_fusionhdtv = {
198
	.demod_address = 0x0f,
199
	.demod_init    = dvico_fusionhdtv_demod_init,
L
Linus Torvalds 已提交
200 201 202 203 204 205
};

static struct mt352_config dntv_live_dvbt_config = {
	.demod_address = 0x0f,
	.demod_init    = dntv_live_dvbt_demod_init,
};
206

207
static struct mt352_config dvico_fusionhdtv_dual = {
208
	.demod_address = 0x0f,
209 210 211
	.demod_init    = dvico_dual_demod_init,
};

212
#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
{
	static u8 clock_config []  = { 0x89, 0x38, 0x38 };
	static u8 reset []         = { 0x50, 0x80 };
	static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
	static u8 agc_cfg []       = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
				       0x00, 0xFF, 0x00, 0x40, 0x40 };
	static u8 dntv_extra[]     = { 0xB5, 0x7A };
	static u8 capt_range_cfg[] = { 0x75, 0x32 };

	mt352_write(fe, clock_config,   sizeof(clock_config));
	udelay(2000);
	mt352_write(fe, reset,          sizeof(reset));
	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));

	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
	udelay(2000);
	mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));

	return 0;
}

236 237 238
static struct mt352_config dntv_live_dvbt_pro_config = {
	.demod_address = 0x0f,
	.no_tuner      = 1,
239
	.demod_init    = dntv_live_dvbt_pro_demod_init,
240 241
};
#endif
L
Linus Torvalds 已提交
242

243
static struct zl10353_config dvico_fusionhdtv_hybrid = {
244
	.demod_address = 0x0f,
245
	.no_tuner      = 1,
246 247
};

248 249 250 251 252 253 254 255 256 257 258 259 260
static struct zl10353_config dvico_fusionhdtv_xc3028 = {
	.demod_address = 0x0f,
	.if2           = 45600,
	.no_tuner      = 1,
};

static struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
	.demod_address = 0x0f,
	.if2 = 4560,
	.no_tuner = 1,
	.demod_init = dvico_fusionhdtv_demod_init,
};

261
static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
262
	.demod_address = 0x0f,
263 264
};

L
Linus Torvalds 已提交
265 266
static struct cx22702_config connexant_refboard_config = {
	.demod_address = 0x43,
267
	.output_mode   = CX22702_SERIAL_OUTPUT,
L
Linus Torvalds 已提交
268 269
};

270
static struct cx22702_config hauppauge_hvr_config = {
271 272 273
	.demod_address = 0x63,
	.output_mode   = CX22702_SERIAL_OUTPUT,
};
L
Linus Torvalds 已提交
274

275
static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
L
Linus Torvalds 已提交
276 277 278 279 280 281
{
	struct cx8802_dev *dev= fe->dvb->priv;
	dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
	return 0;
}

A
Adrian Bunk 已提交
282
static struct or51132_config pchdtv_hd3000 = {
283 284
	.demod_address = 0x15,
	.set_ts_params = or51132_set_ts_param,
L
Linus Torvalds 已提交
285 286
};

287
static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
288 289 290 291
{
	struct cx8802_dev *dev= fe->dvb->priv;
	struct cx88_core *core = dev->core;

292
	dprintk(1, "%s: index = %d\n", __func__, index);
293 294 295 296 297 298 299
	if (index == 0)
		cx_clear(MO_GP0_IO, 8);
	else
		cx_set(MO_GP0_IO, 8);
	return 0;
}

300
static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
301 302 303 304 305 306 307 308 309
{
	struct cx8802_dev *dev= fe->dvb->priv;
	if (is_punctured)
		dev->ts_gen_cntrl |= 0x04;
	else
		dev->ts_gen_cntrl &= ~0x04;
	return 0;
}

310
static struct lgdt330x_config fusionhdtv_3_gold = {
311 312 313 314
	.demod_address = 0x0e,
	.demod_chip    = LGDT3302,
	.serial_mpeg   = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
	.set_ts_params = lgdt330x_set_ts_param,
315
};
316 317

static struct lgdt330x_config fusionhdtv_5_gold = {
318 319 320 321
	.demod_address = 0x0e,
	.demod_chip    = LGDT3303,
	.serial_mpeg   = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
	.set_ts_params = lgdt330x_set_ts_param,
322
};
323 324

static struct lgdt330x_config pchdtv_hd5500 = {
325 326 327 328
	.demod_address = 0x59,
	.demod_chip    = LGDT3303,
	.serial_mpeg   = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
	.set_ts_params = lgdt330x_set_ts_param,
329
};
330

331
static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
332 333 334 335 336 337 338
{
	struct cx8802_dev *dev= fe->dvb->priv;
	dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
	return 0;
}

static struct nxt200x_config ati_hdtvwonder = {
339 340
	.demod_address = 0x0a,
	.set_ts_params = nxt200x_set_ts_param,
341 342
};

343 344 345 346
static int cx24123_set_ts_param(struct dvb_frontend* fe,
	int is_punctured)
{
	struct cx8802_dev *dev= fe->dvb->priv;
347
	dev->ts_gen_cntrl = 0x02;
348 349 350
	return 0;
}

351 352
static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
				       fe_sec_voltage_t voltage)
353 354 355 356
{
	struct cx8802_dev *dev= fe->dvb->priv;
	struct cx88_core *core = dev->core;

357
	if (voltage == SEC_VOLTAGE_OFF)
358
		cx_write(MO_GP0_IO, 0x000006fb);
359
	else
360 361 362 363 364
		cx_write(MO_GP0_IO, 0x000006f9);

	if (core->prev_set_voltage)
		return core->prev_set_voltage(fe, voltage);
	return 0;
365 366
}

367 368
static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
				      fe_sec_voltage_t voltage)
369 370 371 372 373 374 375 376 377 378 379 380 381 382
{
	struct cx8802_dev *dev= fe->dvb->priv;
	struct cx88_core *core = dev->core;

	if (voltage == SEC_VOLTAGE_OFF) {
		dprintk(1,"LNB Voltage OFF\n");
		cx_write(MO_GP0_IO, 0x0000efff);
	}

	if (core->prev_set_voltage)
		return core->prev_set_voltage(fe, voltage);
	return 0;
}

383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
				      fe_sec_voltage_t voltage)
{
	struct cx8802_dev *dev= fe->dvb->priv;
	struct cx88_core *core = dev->core;

	switch (voltage) {
		case SEC_VOLTAGE_13:
			printk("LNB Voltage SEC_VOLTAGE_13\n");
			cx_write(MO_GP0_IO, 0x00006040);
			break;
		case SEC_VOLTAGE_18:
			printk("LNB Voltage SEC_VOLTAGE_18\n");
			cx_write(MO_GP0_IO, 0x00006060);
			break;
		case SEC_VOLTAGE_OFF:
			printk("LNB Voltage SEC_VOLTAGE_off\n");
			break;
	}

	if (core->prev_set_voltage)
		return core->prev_set_voltage(fe, voltage);
	return 0;
}

408
static int cx88_pci_nano_callback(void *ptr, int command, int arg)
409 410 411 412 413 414
{
	struct cx88_core *core = ptr;

	switch (command) {
	case XC2028_TUNER_RESET:
		/* Send the tuner in then out of reset */
415
		dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg);
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430

		switch (core->boardnr) {
		case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
			/* GPIO-4 xc3028 tuner */

			cx_set(MO_GP0_IO, 0x00001000);
			cx_clear(MO_GP0_IO, 0x00000010);
			msleep(100);
			cx_set(MO_GP0_IO, 0x00000010);
			msleep(100);
			break;
		}

		break;
	case XC2028_RESET_CLK:
431
		dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg);
432 433
		break;
	default:
434
		dprintk(1, "%s: unknown command %d, arg %d\n", __func__,
435 436 437 438 439 440 441
			command, arg);
		return -EINVAL;
	}

	return 0;
}

442
static struct cx24123_config geniatech_dvbs_config = {
443 444
	.demod_address = 0x55,
	.set_ts_params = cx24123_set_ts_param,
445 446
};

447
static struct cx24123_config hauppauge_novas_config = {
448 449
	.demod_address = 0x55,
	.set_ts_params = cx24123_set_ts_param,
450 451 452
};

static struct cx24123_config kworld_dvbs_100_config = {
453 454
	.demod_address = 0x15,
	.set_ts_params = cx24123_set_ts_param,
455
	.lnb_polarity  = 1,
456 457
};

458 459 460 461 462 463 464
static struct s5h1409_config pinnacle_pctv_hd_800i_config = {
	.demod_address = 0x32 >> 1,
	.output_mode   = S5H1409_PARALLEL_OUTPUT,
	.gpio	       = S5H1409_GPIO_ON,
	.qam_if	       = 44000,
	.inversion     = S5H1409_INVERSION_OFF,
	.status_mode   = S5H1409_DEMODLOCKING,
465
	.mpeg_timing   = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
466 467
};

468 469 470 471 472 473 474 475 476
static struct s5h1409_config dvico_hdtv5_pci_nano_config = {
	.demod_address = 0x32 >> 1,
	.output_mode   = S5H1409_SERIAL_OUTPUT,
	.gpio          = S5H1409_GPIO_OFF,
	.inversion     = S5H1409_INVERSION_OFF,
	.status_mode   = S5H1409_DEMODLOCKING,
	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
};

477 478 479 480 481 482 483 484 485
static struct s5h1409_config kworld_atsc_120_config = {
	.demod_address = 0x32 >> 1,
	.output_mode   = S5H1409_SERIAL_OUTPUT,
	.gpio	       = S5H1409_GPIO_OFF,
	.inversion     = S5H1409_INVERSION_OFF,
	.status_mode   = S5H1409_DEMODLOCKING,
	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
};

486 487 488 489 490 491
static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
	.i2c_address	= 0x64,
	.if_khz		= 5380,
	.tuner_callback	= cx88_tuner_callback,
};

492 493 494 495 496
static struct zl10353_config cx88_geniatech_x8000_mt = {
       .demod_address = (0x1e >> 1),
       .no_tuner = 1,
};

497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
static struct s5h1411_config dvico_fusionhdtv7_config = {
	.output_mode   = S5H1411_SERIAL_OUTPUT,
	.gpio          = S5H1411_GPIO_ON,
	.mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
	.qam_if        = S5H1411_IF_44000,
	.vsb_if        = S5H1411_IF_44000,
	.inversion     = S5H1411_INVERSION_OFF,
	.status_mode   = S5H1411_DEMODLOCKING
};

static struct xc5000_config dvico_fusionhdtv7_tuner_config = {
	.i2c_address    = 0xc2 >> 1,
	.if_khz         = 5380,
	.tuner_callback = cx88_tuner_callback,
};

513 514 515
static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
{
	struct dvb_frontend *fe;
516
	struct xc2028_ctrl ctl;
517 518 519
	struct xc2028_config cfg = {
		.i2c_adap  = &dev->core->i2c_adap,
		.i2c_addr  = addr,
520 521
		.ctrl      = &ctl,
		.callback  = cx88_tuner_callback,
522 523
	};

524 525 526 527 528 529 530
	if (!dev->dvb.frontend) {
		printk(KERN_ERR "%s/2: dvb frontend not attached. "
				"Can't attach xc3028\n",
		       dev->core->name);
		return -EINVAL;
	}

531 532 533 534 535 536 537
	/*
	 * Some xc3028 devices may be hidden by an I2C gate. This is known
	 * to happen with some s5h1409-based devices.
	 * Now that I2C gate is open, sets up xc3028 configuration
	 */
	cx88_setup_xc3028(dev->core, &ctl);

538 539 540 541 542 543 544 545 546 547 548 549
	fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg);
	if (!fe) {
		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
		       dev->core->name);
		return -EINVAL;
	}

	printk(KERN_INFO "%s/2: xc3028 attached\n",
	       dev->core->name);

	return 0;
}
550

551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
static int cx24116_set_ts_param(struct dvb_frontend *fe,
	int is_punctured)
{
	struct cx8802_dev *dev = fe->dvb->priv;
	dev->ts_gen_cntrl = 0x2;

	return 0;
}

static int cx24116_reset_device(struct dvb_frontend *fe)
{
	struct cx8802_dev *dev = fe->dvb->priv;
	struct cx88_core *core = dev->core;

	/* Reset the part */
	cx_write(MO_SRST_IO, 0);
	msleep(10);
	cx_write(MO_SRST_IO, 1);
	msleep(10);

	return 0;
}

static struct cx24116_config hauppauge_hvr4000_config = {
	.demod_address          = 0x05,
	.set_ts_params          = cx24116_set_ts_param,
	.reset_device           = cx24116_reset_device,
};

580 581 582 583 584 585
static struct cx24116_config tevii_s460_config = {
	.demod_address = 0x55,
	.set_ts_params = cx24116_set_ts_param,
	.reset_device  = cx24116_reset_device,
};

586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
static struct stv0299_config tevii_tuner_sharp_config = {
	.demod_address = 0x68,
	.inittab = sharp_z0194a__inittab,
	.mclk = 88000000UL,
	.invert = 1,
	.skip_reinit = 0,
	.lock_output = 1,
	.volt13_op0_op1 = STV0299_VOLT13_OP1,
	.min_delay_ms = 100,
	.set_symbol_rate = sharp_z0194a__set_symbol_rate,
	.set_ts_params = cx24116_set_ts_param,
};

static struct stv0288_config tevii_tuner_earda_config = {
	.demod_address = 0x68,
	.min_delay_ms = 100,
	.set_ts_params = cx24116_set_ts_param,
};

L
Linus Torvalds 已提交
605 606
static int dvb_register(struct cx8802_dev *dev)
{
607 608
	struct cx88_core *core = dev->core;

L
Linus Torvalds 已提交
609
	/* init struct videobuf_dvb */
610
	dev->dvb.name = core->name;
L
Linus Torvalds 已提交
611 612 613
	dev->ts_gen_cntrl = 0x0c;

	/* init frontend */
614
	switch (core->boardnr) {
L
Linus Torvalds 已提交
615
	case CX88_BOARD_HAUPPAUGE_DVB_T1:
616
		dev->dvb.frontend = dvb_attach(cx22702_attach,
617
					       &connexant_refboard_config,
618
					       &core->i2c_adap);
619
		if (dev->dvb.frontend != NULL) {
620 621 622 623
			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
					0x61, &core->i2c_adap,
					DVB_PLL_THOMSON_DTT759X))
				goto frontend_detach;
624
		}
L
Linus Torvalds 已提交
625
		break;
626
	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
L
Linus Torvalds 已提交
627
	case CX88_BOARD_CONEXANT_DVB_T1:
628
	case CX88_BOARD_KWORLD_DVB_T_CX22702:
629
	case CX88_BOARD_WINFAST_DTV1000:
630 631
		dev->dvb.frontend = dvb_attach(cx22702_attach,
					       &connexant_refboard_config,
632
					       &core->i2c_adap);
633
		if (dev->dvb.frontend != NULL) {
634 635 636 637
			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
					0x60, &core->i2c_adap,
					DVB_PLL_THOMSON_DTT7579))
				goto frontend_detach;
638
		}
L
Linus Torvalds 已提交
639
		break;
640
	case CX88_BOARD_WINFAST_DTV2000H:
641 642
	case CX88_BOARD_HAUPPAUGE_HVR1100:
	case CX88_BOARD_HAUPPAUGE_HVR1100LP:
643 644
	case CX88_BOARD_HAUPPAUGE_HVR1300:
	case CX88_BOARD_HAUPPAUGE_HVR3000:
645
		dev->dvb.frontend = dvb_attach(cx22702_attach,
646
					       &hauppauge_hvr_config,
647
					       &core->i2c_adap);
648
		if (dev->dvb.frontend != NULL) {
649 650 651 652
			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
				   &core->i2c_adap, 0x61,
				   TUNER_PHILIPS_FMD1216ME_MK3))
				goto frontend_detach;
653
		}
654
		break;
655
	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
656 657
		dev->dvb.frontend = dvb_attach(mt352_attach,
					       &dvico_fusionhdtv,
658
					       &core->i2c_adap);
659
		if (dev->dvb.frontend != NULL) {
660 661 662
			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
				goto frontend_detach;
663
			break;
664
		}
665
		/* ZL10353 replaces MT352 on later cards */
666 667
		dev->dvb.frontend = dvb_attach(zl10353_attach,
					       &dvico_fusionhdtv_plus_v1_1,
668
					       &core->i2c_adap);
669
		if (dev->dvb.frontend != NULL) {
670 671 672
			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
				goto frontend_detach;
673
		}
674 675 676 677
		break;
	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
		/* The tin box says DEE1601, but it seems to be DTT7579
		 * compatible, with a slightly different MT352 AGC gain. */
678 679
		dev->dvb.frontend = dvb_attach(mt352_attach,
					       &dvico_fusionhdtv_dual,
680
					       &core->i2c_adap);
681
		if (dev->dvb.frontend != NULL) {
682 683 684
			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
				goto frontend_detach;
685 686 687
			break;
		}
		/* ZL10353 replaces MT352 on later cards */
688 689
		dev->dvb.frontend = dvb_attach(zl10353_attach,
					       &dvico_fusionhdtv_plus_v1_1,
690
					       &core->i2c_adap);
691
		if (dev->dvb.frontend != NULL) {
692 693 694
			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
				goto frontend_detach;
695
		}
L
Linus Torvalds 已提交
696
		break;
697
	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
698 699
		dev->dvb.frontend = dvb_attach(mt352_attach,
					       &dvico_fusionhdtv,
700
					       &core->i2c_adap);
701
		if (dev->dvb.frontend != NULL) {
702 703 704
			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
					0x61, NULL, DVB_PLL_LG_Z201))
				goto frontend_detach;
705
		}
L
Linus Torvalds 已提交
706 707 708
		break;
	case CX88_BOARD_KWORLD_DVB_T:
	case CX88_BOARD_DNTV_LIVE_DVB_T:
M
Mauro Carvalho Chehab 已提交
709
	case CX88_BOARD_ADSTECH_DVB_T_PCI:
710 711
		dev->dvb.frontend = dvb_attach(mt352_attach,
					       &dntv_live_dvbt_config,
712
					       &core->i2c_adap);
713
		if (dev->dvb.frontend != NULL) {
714 715 716
			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
					0x61, NULL, DVB_PLL_UNKNOWN_1))
				goto frontend_detach;
717
		}
L
Linus Torvalds 已提交
718
		break;
719
	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
720
#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
721
		/* MT352 is on a secondary I2C bus made from some GPIO lines */
722
		dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
723
					       &dev->vp3054->adap);
724
		if (dev->dvb.frontend != NULL) {
725 726 727 728
			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
					&core->i2c_adap, 0x61,
					TUNER_PHILIPS_FMD1216ME_MK3))
				goto frontend_detach;
729
		}
730
#else
731 732
		printk(KERN_ERR "%s/2: built without vp3054 support\n",
				core->name);
733 734
#endif
		break;
735
	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
736 737
		dev->dvb.frontend = dvb_attach(zl10353_attach,
					       &dvico_fusionhdtv_hybrid,
738
					       &core->i2c_adap);
739
		if (dev->dvb.frontend != NULL) {
740 741 742 743
			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
				   &core->i2c_adap, 0x61,
				   TUNER_THOMSON_FE6600))
				goto frontend_detach;
744
		}
745
		break;
746 747 748
	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
		dev->dvb.frontend = dvb_attach(zl10353_attach,
					       &dvico_fusionhdtv_xc3028,
749
					       &core->i2c_adap);
750 751 752
		if (dev->dvb.frontend == NULL)
			dev->dvb.frontend = dvb_attach(mt352_attach,
						&dvico_fusionhdtv_mt352_xc3028,
753
						&core->i2c_adap);
754 755 756 757 758 759 760
		/*
		 * On this board, the demod provides the I2C bus pullup.
		 * We must not permit gate_ctrl to be performed, or
		 * the xc3028 cannot communicate on the bus.
		 */
		if (dev->dvb.frontend)
			dev->dvb.frontend->ops.i2c_gate_ctrl = NULL;
761 762
		if (attach_xc3028(0x61, dev) < 0)
			return -EINVAL;
763
		break;
L
Linus Torvalds 已提交
764
	case CX88_BOARD_PCHDTV_HD3000:
765
		dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
766
					       &core->i2c_adap);
767
		if (dev->dvb.frontend != NULL) {
768 769 770 771
			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
					&core->i2c_adap, 0x61,
					TUNER_THOMSON_DTT761X))
				goto frontend_detach;
772
		}
L
Linus Torvalds 已提交
773
		break;
774 775 776
	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
		dev->ts_gen_cntrl = 0x08;

777
		/* Do a hardware reset of chip before using it. */
778 779
		cx_clear(MO_GP0_IO, 1);
		mdelay(100);
780
		cx_set(MO_GP0_IO, 1);
781
		mdelay(200);
782 783

		/* Select RF connector callback */
784
		fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
785 786
		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
					       &fusionhdtv_3_gold,
787
					       &core->i2c_adap);
788
		if (dev->dvb.frontend != NULL) {
789 790 791 792
			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
					&core->i2c_adap, 0x61,
					TUNER_MICROTUNE_4042FI5))
				goto frontend_detach;
793 794
		}
		break;
795 796 797
	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
		dev->ts_gen_cntrl = 0x08;

798
		/* Do a hardware reset of chip before using it. */
799 800
		cx_clear(MO_GP0_IO, 1);
		mdelay(100);
M
Michael Krufky 已提交
801
		cx_set(MO_GP0_IO, 9);
802
		mdelay(200);
803 804
		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
					       &fusionhdtv_3_gold,
805
					       &core->i2c_adap);
806
		if (dev->dvb.frontend != NULL) {
807 808 809 810
			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
					&core->i2c_adap, 0x61,
					TUNER_THOMSON_DTT761X))
				goto frontend_detach;
811 812
		}
		break;
813 814 815
	case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
		dev->ts_gen_cntrl = 0x08;

816
		/* Do a hardware reset of chip before using it. */
817 818 819 820
		cx_clear(MO_GP0_IO, 1);
		mdelay(100);
		cx_set(MO_GP0_IO, 1);
		mdelay(200);
821 822
		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
					       &fusionhdtv_5_gold,
823
					       &core->i2c_adap);
824
		if (dev->dvb.frontend != NULL) {
825 826 827 828 829 830 831
			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
					&core->i2c_adap, 0x61,
					TUNER_LG_TDVS_H06XF))
				goto frontend_detach;
			if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
				   &core->i2c_adap, 0x43))
				goto frontend_detach;
832 833
		}
		break;
834 835 836
	case CX88_BOARD_PCHDTV_HD5500:
		dev->ts_gen_cntrl = 0x08;

837
		/* Do a hardware reset of chip before using it. */
838 839 840 841
		cx_clear(MO_GP0_IO, 1);
		mdelay(100);
		cx_set(MO_GP0_IO, 1);
		mdelay(200);
842 843
		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
					       &pchdtv_hd5500,
844
					       &core->i2c_adap);
845
		if (dev->dvb.frontend != NULL) {
846 847 848 849 850 851 852
			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
					&core->i2c_adap, 0x61,
					TUNER_LG_TDVS_H06XF))
				goto frontend_detach;
			if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
				   &core->i2c_adap, 0x43))
				goto frontend_detach;
853 854
		}
		break;
855
	case CX88_BOARD_ATI_HDTVWONDER:
856 857
		dev->dvb.frontend = dvb_attach(nxt200x_attach,
					       &ati_hdtvwonder,
858
					       &core->i2c_adap);
859
		if (dev->dvb.frontend != NULL) {
860 861 862 863
			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
					&core->i2c_adap, 0x61,
					TUNER_PHILIPS_TUV1236D))
				goto frontend_detach;
864
		}
865 866 867
		break;
	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
868 869
		dev->dvb.frontend = dvb_attach(cx24123_attach,
					       &hauppauge_novas_config,
870
					       &core->i2c_adap);
871
		if (dev->dvb.frontend) {
872
			if (!dvb_attach(isl6421_attach, dev->dvb.frontend,
873
					&core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
874
				goto frontend_detach;
875
		}
876 877
		break;
	case CX88_BOARD_KWORLD_DVBS_100:
878 879
		dev->dvb.frontend = dvb_attach(cx24123_attach,
					       &kworld_dvbs_100_config,
880
					       &core->i2c_adap);
881
		if (dev->dvb.frontend) {
882
			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
883
			dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
884
		}
885
		break;
886
	case CX88_BOARD_GENIATECH_DVBS:
887 888
		dev->dvb.frontend = dvb_attach(cx24123_attach,
					       &geniatech_dvbs_config,
889
					       &core->i2c_adap);
890
		if (dev->dvb.frontend) {
891
			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
892 893 894
			dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
		}
		break;
895 896 897
	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
		dev->dvb.frontend = dvb_attach(s5h1409_attach,
					       &pinnacle_pctv_hd_800i_config,
898
					       &core->i2c_adap);
899
		if (dev->dvb.frontend != NULL) {
900 901
			if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
					&core->i2c_adap,
902
					&pinnacle_pctv_hd_800i_tuner_config))
903
				goto frontend_detach;
904 905
		}
		break;
906 907 908
	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
		dev->dvb.frontend = dvb_attach(s5h1409_attach,
						&dvico_hdtv5_pci_nano_config,
909
						&core->i2c_adap);
910 911 912
		if (dev->dvb.frontend != NULL) {
			struct dvb_frontend *fe;
			struct xc2028_config cfg = {
913
				.i2c_adap  = &core->i2c_adap,
914
				.i2c_addr  = 0x61,
915
				.callback  = cx88_pci_nano_callback,
916 917
			};
			static struct xc2028_ctrl ctl = {
918
				.fname       = XC2028_DEFAULT_FIRMWARE,
919
				.max_len     = 64,
920
				.scode_table = XC3028_FE_OREN538,
921 922 923 924 925 926 927 928
			};

			fe = dvb_attach(xc2028_attach,
					dev->dvb.frontend, &cfg);
			if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
				fe->ops.tuner_ops.set_config(fe, &ctl);
		}
		break;
929 930 931
	 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
		dev->dvb.frontend = dvb_attach(zl10353_attach,
					       &cx88_geniatech_x8000_mt,
932
					       &core->i2c_adap);
933
		if (attach_xc3028(0x61, dev) < 0)
934
			goto frontend_detach;
935 936
		break;
	 case CX88_BOARD_GENIATECH_X8000_MT:
937
		dev->ts_gen_cntrl = 0x00;
938 939 940

		dev->dvb.frontend = dvb_attach(zl10353_attach,
					       &cx88_geniatech_x8000_mt,
941
					       &core->i2c_adap);
942
		if (attach_xc3028(0x61, dev) < 0)
943
			goto frontend_detach;
944
		break;
945 946 947
	 case CX88_BOARD_KWORLD_ATSC_120:
		dev->dvb.frontend = dvb_attach(s5h1409_attach,
					       &kworld_atsc_120_config,
948
					       &core->i2c_adap);
949
		if (attach_xc3028(0x61, dev) < 0)
950
			goto frontend_detach;
951
		break;
952 953 954
	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
		dev->dvb.frontend = dvb_attach(s5h1411_attach,
					       &dvico_fusionhdtv7_config,
955
					       &core->i2c_adap);
956
		if (dev->dvb.frontend != NULL) {
957 958
			if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
					&core->i2c_adap,
959
					&dvico_fusionhdtv7_tuner_config))
960
				goto frontend_detach;
961 962
		}
		break;
963 964 965 966 967 968 969 970 971
	case CX88_BOARD_HAUPPAUGE_HVR4000:
	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
		/* Support for DVB-S only, not DVB-T support */
		dev->dvb.frontend = dvb_attach(cx24116_attach,
			&hauppauge_hvr4000_config,
			&dev->core->i2c_adap);
		if (dev->dvb.frontend) {
			dvb_attach(isl6421_attach, dev->dvb.frontend,
				&dev->core->i2c_adap,
972
				0x08, ISL6421_DCL, 0x00);
973 974
		}
		break;
975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999
	case CX88_BOARD_TEVII_S420:
		dev->dvb.frontend = dvb_attach(stv0299_attach,
						&tevii_tuner_sharp_config,
						&core->i2c_adap);
		if (dev->dvb.frontend != NULL) {
			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
					&core->i2c_adap, DVB_PLL_OPERA1))
				goto frontend_detach;
			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
			dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;

		} else {
			dev->dvb.frontend = dvb_attach(stv0288_attach,
							    &tevii_tuner_earda_config,
							    &core->i2c_adap);
				if (dev->dvb.frontend != NULL) {
					if (!dvb_attach(stb6000_attach, dev->dvb.frontend, 0x61,
						&core->i2c_adap))
					goto frontend_detach;
				core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
				dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;

			}
		}
		break;
1000
	case CX88_BOARD_TEVII_S460:
1001
		dev->dvb.frontend = dvb_attach(cx24116_attach,
1002 1003
					       &tevii_s460_config,
					       &core->i2c_adap);
1004 1005 1006 1007 1008 1009 1010 1011 1012
		if (dev->dvb.frontend != NULL) {
			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
			dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
		}
		break;
	case CX88_BOARD_OMICOM_SS4_PCI:
		dev->dvb.frontend = dvb_attach(cx24116_attach,
					       &hauppauge_hvr4000_config,
					       &core->i2c_adap);
1013 1014 1015 1016 1017 1018 1019 1020 1021
		if (dev->dvb.frontend != NULL) {
			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
			dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
		}
		break;
	case CX88_BOARD_TBS_8920:
		dev->dvb.frontend = dvb_attach(cx24116_attach,
					       &hauppauge_hvr4000_config,
					       &core->i2c_adap);
1022 1023 1024 1025 1026
		if (dev->dvb.frontend != NULL) {
			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
			dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
		}
		break;
L
Linus Torvalds 已提交
1027
	default:
1028
		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1029
		       core->name);
L
Linus Torvalds 已提交
1030 1031 1032
		break;
	}
	if (NULL == dev->dvb.frontend) {
1033 1034
		printk(KERN_ERR
		       "%s/2: frontend initialization failed\n",
1035
		       core->name);
1036
		return -EINVAL;
1037 1038
	}

1039 1040
	/* Ensure all frontends negotiate bus access */
	dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
L
Linus Torvalds 已提交
1041

1042
	/* Put the analog decoder in standby to keep it quiet */
1043
	cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
1044

L
Linus Torvalds 已提交
1045
	/* register everything */
1046 1047
	return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev,
				     &dev->pci->dev, adapter_nr);
1048 1049 1050 1051 1052 1053 1054

frontend_detach:
	if (dev->dvb.frontend) {
		dvb_frontend_detach(dev->dvb.frontend);
		dev->dvb.frontend = NULL;
	}
	return -EINVAL;
L
Linus Torvalds 已提交
1055 1056 1057 1058
}

/* ----------------------------------------------------------- */

1059 1060
/* CX8802 MPEG -> mini driver - We have been given the hardware */
static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
L
Linus Torvalds 已提交
1061
{
1062 1063
	struct cx88_core *core = drv->core;
	int err = 0;
1064
	dprintk( 1, "%s\n", __func__);
1065

1066
	switch (core->boardnr) {
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
	case CX88_BOARD_HAUPPAUGE_HVR1300:
		/* We arrive here with either the cx23416 or the cx22702
		 * on the bus. Take the bus from the cx23416 and enable the
		 * cx22702 demod
		 */
		cx_set(MO_GP0_IO,   0x00000080); /* cx22702 out of reset and enable */
		cx_clear(MO_GP0_IO, 0x00000004);
		udelay(1000);
		break;
	default:
		err = -ENODEV;
	}
	return err;
}

/* CX8802 MPEG -> mini driver - We no longer have the hardware */
static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
{
	struct cx88_core *core = drv->core;
	int err = 0;
1087
	dprintk( 1, "%s\n", __func__);
1088

1089
	switch (core->boardnr) {
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
	case CX88_BOARD_HAUPPAUGE_HVR1300:
		/* Do Nothing, leave the cx22702 on the bus. */
		break;
	default:
		err = -ENODEV;
	}
	return err;
}

static int cx8802_dvb_probe(struct cx8802_driver *drv)
{
	struct cx88_core *core = drv->core;
	struct cx8802_dev *dev = drv->core->dvbdev;
L
Linus Torvalds 已提交
1103 1104
	int err;

1105
	dprintk( 1, "%s\n", __func__);
1106
	dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1107
		core->boardnr,
1108 1109 1110
		core->name,
		core->pci_bus,
		core->pci_slot);
L
Linus Torvalds 已提交
1111 1112

	err = -ENODEV;
1113
	if (!(core->board.mpeg & CX88_MPEG_DVB))
L
Linus Torvalds 已提交
1114 1115
		goto fail_core;

1116
	/* If vp3054 isn't enabled, a stub will just return 0 */
1117 1118
	err = vp3054_i2c_probe(dev);
	if (0 != err)
1119
		goto fail_core;
1120

L
Linus Torvalds 已提交
1121
	/* dvb stuff */
1122
	printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1123 1124
	videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops,
			    &dev->pci->dev, &dev->slock,
L
Linus Torvalds 已提交
1125 1126 1127 1128 1129
			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
			    V4L2_FIELD_TOP,
			    sizeof(struct cx88_buffer),
			    dev);
	err = dvb_register(dev);
1130
	if (err != 0)
1131 1132
		printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
		       core->name, err);
L
Linus Torvalds 已提交
1133 1134 1135 1136 1137

 fail_core:
	return err;
}

1138
static int cx8802_dvb_remove(struct cx8802_driver *drv)
L
Linus Torvalds 已提交
1139
{
1140
	struct cx8802_dev *dev = drv->core->dvbdev;
1141

L
Linus Torvalds 已提交
1142
	/* dvb */
1143 1144
	if (dev->dvb.frontend)
		videobuf_dvb_unregister(&dev->dvb);
L
Linus Torvalds 已提交
1145

1146 1147
	vp3054_i2c_remove(dev);

1148
	return 0;
L
Linus Torvalds 已提交
1149 1150
}

1151 1152 1153 1154 1155 1156 1157
static struct cx8802_driver cx8802_dvb_driver = {
	.type_id        = CX88_MPEG_DVB,
	.hw_access      = CX8802_DRVCTL_SHARED,
	.probe          = cx8802_dvb_probe,
	.remove         = cx8802_dvb_remove,
	.advise_acquire = cx8802_dvb_advise_acquire,
	.advise_release = cx8802_dvb_advise_release,
L
Linus Torvalds 已提交
1158 1159 1160 1161
};

static int dvb_init(void)
{
1162
	printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n",
L
Linus Torvalds 已提交
1163 1164 1165 1166 1167 1168 1169
	       (CX88_VERSION_CODE >> 16) & 0xff,
	       (CX88_VERSION_CODE >>  8) & 0xff,
	       CX88_VERSION_CODE & 0xff);
#ifdef SNAPSHOT
	printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
	       SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
#endif
1170
	return cx8802_register_driver(&cx8802_dvb_driver);
L
Linus Torvalds 已提交
1171 1172 1173 1174
}

static void dvb_fini(void)
{
1175
	cx8802_unregister_driver(&cx8802_dvb_driver);
L
Linus Torvalds 已提交
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
}

module_init(dvb_init);
module_exit(dvb_fini);

/*
 * Local variables:
 * c-basic-offset: 8
 * compile-command: "make DVB=1"
 * End:
 */