cx88-dvb.c 37.4 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

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;
119 120 121 122 123 124 125 126
	int fe_id;

	fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
	if (!fe_id) {
		printk(KERN_ERR "%s() No frontend found\n", __FUNCTION__);
		return -EINVAL;
	}

127 128 129

	drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
	if (drv) {
130 131
		if (acquire){
			dev->frontends.active_fe_id = fe_id;
132
			ret = drv->request_acquire(drv);
133
		} else {
134
			ret = drv->request_release(drv);
135 136
			dev->frontends.active_fe_id = 0;
		}
137 138 139 140 141 142 143
	}

	return ret;
}

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

144
static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
L
Linus Torvalds 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
{
	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;
}

164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
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 已提交
185 186 187 188 189 190
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,
191
				       0x00, 0xFF, 0x00, 0x40, 0x40 };
L
Linus Torvalds 已提交
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
	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 = {
209
	.demod_address = 0x0f,
210
	.demod_init    = dvico_fusionhdtv_demod_init,
L
Linus Torvalds 已提交
211 212 213 214 215 216
};

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

218
static struct mt352_config dvico_fusionhdtv_dual = {
219
	.demod_address = 0x0f,
220 221 222
	.demod_init    = dvico_dual_demod_init,
};

223
#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
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;
}

247 248 249
static struct mt352_config dntv_live_dvbt_pro_config = {
	.demod_address = 0x0f,
	.no_tuner      = 1,
250
	.demod_init    = dntv_live_dvbt_pro_demod_init,
251 252
};
#endif
L
Linus Torvalds 已提交
253

254
static struct zl10353_config dvico_fusionhdtv_hybrid = {
255
	.demod_address = 0x0f,
256
	.no_tuner      = 1,
257 258
};

259 260 261 262 263 264 265 266 267 268 269 270 271
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,
};

272
static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
273
	.demod_address = 0x0f,
274 275
};

L
Linus Torvalds 已提交
276 277
static struct cx22702_config connexant_refboard_config = {
	.demod_address = 0x43,
278
	.output_mode   = CX22702_SERIAL_OUTPUT,
L
Linus Torvalds 已提交
279 280
};

281
static struct cx22702_config hauppauge_hvr_config = {
282 283 284
	.demod_address = 0x63,
	.output_mode   = CX22702_SERIAL_OUTPUT,
};
L
Linus Torvalds 已提交
285

286
static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
L
Linus Torvalds 已提交
287 288 289 290 291 292
{
	struct cx8802_dev *dev= fe->dvb->priv;
	dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
	return 0;
}

A
Adrian Bunk 已提交
293
static struct or51132_config pchdtv_hd3000 = {
294 295
	.demod_address = 0x15,
	.set_ts_params = or51132_set_ts_param,
L
Linus Torvalds 已提交
296 297
};

298
static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
299 300 301 302
{
	struct cx8802_dev *dev= fe->dvb->priv;
	struct cx88_core *core = dev->core;

303
	dprintk(1, "%s: index = %d\n", __func__, index);
304 305 306 307 308 309 310
	if (index == 0)
		cx_clear(MO_GP0_IO, 8);
	else
		cx_set(MO_GP0_IO, 8);
	return 0;
}

311
static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
312 313 314 315 316 317 318 319 320
{
	struct cx8802_dev *dev= fe->dvb->priv;
	if (is_punctured)
		dev->ts_gen_cntrl |= 0x04;
	else
		dev->ts_gen_cntrl &= ~0x04;
	return 0;
}

321
static struct lgdt330x_config fusionhdtv_3_gold = {
322 323 324 325
	.demod_address = 0x0e,
	.demod_chip    = LGDT3302,
	.serial_mpeg   = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
	.set_ts_params = lgdt330x_set_ts_param,
326
};
327 328

static struct lgdt330x_config fusionhdtv_5_gold = {
329 330 331 332
	.demod_address = 0x0e,
	.demod_chip    = LGDT3303,
	.serial_mpeg   = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
	.set_ts_params = lgdt330x_set_ts_param,
333
};
334 335

static struct lgdt330x_config pchdtv_hd5500 = {
336 337 338 339
	.demod_address = 0x59,
	.demod_chip    = LGDT3303,
	.serial_mpeg   = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
	.set_ts_params = lgdt330x_set_ts_param,
340
};
341

342
static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
343 344 345 346 347 348 349
{
	struct cx8802_dev *dev= fe->dvb->priv;
	dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
	return 0;
}

static struct nxt200x_config ati_hdtvwonder = {
350 351
	.demod_address = 0x0a,
	.set_ts_params = nxt200x_set_ts_param,
352 353
};

354 355 356 357
static int cx24123_set_ts_param(struct dvb_frontend* fe,
	int is_punctured)
{
	struct cx8802_dev *dev= fe->dvb->priv;
358
	dev->ts_gen_cntrl = 0x02;
359 360 361
	return 0;
}

362 363
static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
				       fe_sec_voltage_t voltage)
364 365 366 367
{
	struct cx8802_dev *dev= fe->dvb->priv;
	struct cx88_core *core = dev->core;

368
	if (voltage == SEC_VOLTAGE_OFF)
369
		cx_write(MO_GP0_IO, 0x000006fb);
370
	else
371 372 373 374 375
		cx_write(MO_GP0_IO, 0x000006f9);

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

378 379
static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
				      fe_sec_voltage_t voltage)
380 381 382 383 384 385 386 387 388 389 390 391 392 393
{
	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;
}

394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
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:
410
		   	printk("LNB Voltage SEC_VOLTAGE_off\n");
411 412 413 414 415 416 417 418
			break;
	}

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

419
static struct cx24123_config geniatech_dvbs_config = {
420 421
	.demod_address = 0x55,
	.set_ts_params = cx24123_set_ts_param,
422 423
};

424
static struct cx24123_config hauppauge_novas_config = {
425 426
	.demod_address = 0x55,
	.set_ts_params = cx24123_set_ts_param,
427 428 429
};

static struct cx24123_config kworld_dvbs_100_config = {
430 431
	.demod_address = 0x15,
	.set_ts_params = cx24123_set_ts_param,
432
	.lnb_polarity  = 1,
433 434
};

435 436 437 438 439 440 441
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,
442
	.mpeg_timing   = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
443 444
};

445 446 447 448 449 450 451 452 453
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,
};

454 455 456 457 458 459 460 461 462
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,
};

463 464 465 466 467
static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
	.i2c_address	= 0x64,
	.if_khz		= 5380,
};

468 469 470 471 472 473
static struct zl10353_config cx88_pinnacle_hybrid_pctv = {
	.demod_address = (0x1e >> 1),
	.no_tuner      = 1,
	.if2           = 45600,
};

474 475 476 477 478
static struct zl10353_config cx88_geniatech_x8000_mt = {
       .demod_address = (0x1e >> 1),
       .no_tuner = 1,
};

479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
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,
};

494 495 496
static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
{
	struct dvb_frontend *fe;
497
	struct videobuf_dvb_frontend *fe0 = NULL;
498
	struct xc2028_ctrl ctl;
499 500 501
	struct xc2028_config cfg = {
		.i2c_adap  = &dev->core->i2c_adap,
		.i2c_addr  = addr,
502
		.ctrl      = &ctl,
503 504
	};

505 506 507 508 509 510
/* Get the first frontend */
	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
	if (!fe0)
		return -EINVAL;

	if (!fe0->dvb.frontend) {
511 512 513 514 515 516
		printk(KERN_ERR "%s/2: dvb frontend not attached. "
				"Can't attach xc3028\n",
		       dev->core->name);
		return -EINVAL;
	}

517 518 519 520 521 522 523
	/*
	 * 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);

524
	fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
525 526 527
	if (!fe) {
		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
		       dev->core->name);
528 529 530
		dvb_frontend_detach(fe0->dvb.frontend);
		dvb_unregister_frontend(fe0->dvb.frontend);
		fe0->dvb.frontend = NULL;
531 532 533 534 535 536 537 538
		return -EINVAL;
	}

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

	return 0;
}
539

540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
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 */
555
	/* Put the cx24116 into reset */
556 557
	cx_write(MO_SRST_IO, 0);
	msleep(10);
558
	/* Take the cx24116 out of reset */
559 560 561 562 563 564 565 566 567 568 569 570
	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,
};

571 572 573 574 575 576
static struct cx24116_config tevii_s460_config = {
	.demod_address = 0x55,
	.set_ts_params = cx24116_set_ts_param,
	.reset_device  = cx24116_reset_device,
};

577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
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 已提交
596 597
static int dvb_register(struct cx8802_dev *dev)
{
598 599 600 601 602 603
	//struct cx88_core *core = dev->core;

	///* init struct videobuf_dvb */
	//fe->dvb.name = core->name;
	//dev->ts_gen_cntrl = 0x0c;

604
	struct cx88_core *core = dev->core;
605
	struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
606

607 608 609 610
	/* Get the first frontend */
	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
	if (!fe0)
		return -EINVAL;
L
Linus Torvalds 已提交
611 612

	/* init frontend */
613
	switch (core->boardnr) {
L
Linus Torvalds 已提交
614
	case CX88_BOARD_HAUPPAUGE_DVB_T1:
615
		fe0->dvb.frontend = dvb_attach(cx22702_attach,
616
					       &connexant_refboard_config,
617
					       &core->i2c_adap);
618 619
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
620 621 622
					0x61, &core->i2c_adap,
					DVB_PLL_THOMSON_DTT759X))
				goto frontend_detach;
623
		}
L
Linus Torvalds 已提交
624
		break;
625
	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
L
Linus Torvalds 已提交
626
	case CX88_BOARD_CONEXANT_DVB_T1:
627
	case CX88_BOARD_KWORLD_DVB_T_CX22702:
628
	case CX88_BOARD_WINFAST_DTV1000:
629
		fe0->dvb.frontend = dvb_attach(cx22702_attach,
630
					       &connexant_refboard_config,
631
					       &core->i2c_adap);
632 633
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
634 635 636
					0x60, &core->i2c_adap,
					DVB_PLL_THOMSON_DTT7579))
				goto frontend_detach;
637
		}
L
Linus Torvalds 已提交
638
		break;
639
	case CX88_BOARD_WINFAST_DTV2000H:
640 641
	case CX88_BOARD_HAUPPAUGE_HVR1100:
	case CX88_BOARD_HAUPPAUGE_HVR1100LP:
642
	case CX88_BOARD_HAUPPAUGE_HVR1300:
643
		fe0->dvb.frontend = dvb_attach(cx22702_attach,
644
					       &hauppauge_hvr_config,
645
					       &core->i2c_adap);
646 647
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
648 649 650
				   &core->i2c_adap, 0x61,
				   TUNER_PHILIPS_FMD1216ME_MK3))
				goto frontend_detach;
651
		}
652
		break;
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
	case CX88_BOARD_HAUPPAUGE_HVR3000:
		/* DVB-S init */
		fe0->dvb.frontend = dvb_attach(cx24123_attach,
			       &hauppauge_novas_config,
			       &dev->core->i2c_adap);
		if (fe0->dvb.frontend) {
			if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
			&dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
				dprintk( 1, "%s(): HVR3000 - DVB-S LNB Init: failed\n", __FUNCTION__);
			}
		} else {
			dprintk( 1, "%s(): HVR3000 - DVB-S Init: failed\n", __FUNCTION__);
		}
		/* DVB-T init */
		fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
		if (fe1) {
			fe1->dvb.frontend = dvb_attach(cx22702_attach,
				&hauppauge_hvr_config,
				&dev->core->i2c_adap);
			if (fe1->dvb.frontend) {
				fe1->dvb.frontend->id = 1;
				if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
						&dev->core->i2c_adap, 0x61,
						TUNER_PHILIPS_FMD1216ME_MK3)) {
					dprintk( 1, "%s(): HVR3000 - DVB-T misc Init: failed\n", __FUNCTION__);
				}
			} else {
				dprintk( 1, "%s(): HVR3000 - DVB-T Init: failed\n", __FUNCTION__);
			}
		} else {
			dprintk( 1, "%s(): HVR3000 - DVB-T Init: can't find frontend 2.\n", __FUNCTION__);
		}
		break;
686
	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
687
		fe0->dvb.frontend = dvb_attach(mt352_attach,
688
					       &dvico_fusionhdtv,
689
					       &core->i2c_adap);
690 691
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
692 693
					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
				goto frontend_detach;
694
			break;
695
		}
696
		/* ZL10353 replaces MT352 on later cards */
697
		fe0->dvb.frontend = dvb_attach(zl10353_attach,
698
					       &dvico_fusionhdtv_plus_v1_1,
699
					       &core->i2c_adap);
700 701
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
702 703
					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
				goto frontend_detach;
704
		}
705 706 707 708
		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. */
709
		fe0->dvb.frontend = dvb_attach(mt352_attach,
710
					       &dvico_fusionhdtv_dual,
711
					       &core->i2c_adap);
712 713
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
714 715
					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
				goto frontend_detach;
716 717 718
			break;
		}
		/* ZL10353 replaces MT352 on later cards */
719
		fe0->dvb.frontend = dvb_attach(zl10353_attach,
720
					       &dvico_fusionhdtv_plus_v1_1,
721
					       &core->i2c_adap);
722 723
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
724 725
					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
				goto frontend_detach;
726
		}
L
Linus Torvalds 已提交
727
		break;
728
	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
729
		fe0->dvb.frontend = dvb_attach(mt352_attach,
730
					       &dvico_fusionhdtv,
731
					       &core->i2c_adap);
732 733
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
734 735
					0x61, NULL, DVB_PLL_LG_Z201))
				goto frontend_detach;
736
		}
L
Linus Torvalds 已提交
737 738 739
		break;
	case CX88_BOARD_KWORLD_DVB_T:
	case CX88_BOARD_DNTV_LIVE_DVB_T:
M
Mauro Carvalho Chehab 已提交
740
	case CX88_BOARD_ADSTECH_DVB_T_PCI:
741
		fe0->dvb.frontend = dvb_attach(mt352_attach,
742
					       &dntv_live_dvbt_config,
743
					       &core->i2c_adap);
744 745
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
746 747
					0x61, NULL, DVB_PLL_UNKNOWN_1))
				goto frontend_detach;
748
		}
L
Linus Torvalds 已提交
749
		break;
750
	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
751
#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
752
		/* MT352 is on a secondary I2C bus made from some GPIO lines */
753
		fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
754
					       &dev->vp3054->adap);
755 756
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
757 758 759
					&core->i2c_adap, 0x61,
					TUNER_PHILIPS_FMD1216ME_MK3))
				goto frontend_detach;
760
		}
761
#else
762 763
		printk(KERN_ERR "%s/2: built without vp3054 support\n",
				core->name);
764 765
#endif
		break;
766
	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
767
		fe0->dvb.frontend = dvb_attach(zl10353_attach,
768
					       &dvico_fusionhdtv_hybrid,
769
					       &core->i2c_adap);
770 771
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
772 773 774
				   &core->i2c_adap, 0x61,
				   TUNER_THOMSON_FE6600))
				goto frontend_detach;
775
		}
776
		break;
777
	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
778
		fe0->dvb.frontend = dvb_attach(zl10353_attach,
779
					       &dvico_fusionhdtv_xc3028,
780
					       &core->i2c_adap);
781 782
		if (fe0->dvb.frontend == NULL)
			fe0->dvb.frontend = dvb_attach(mt352_attach,
783
						&dvico_fusionhdtv_mt352_xc3028,
784
						&core->i2c_adap);
785 786 787 788 789
		/*
		 * 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.
		 */
790 791
		if (fe0->dvb.frontend)
			fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
792 793
		if (attach_xc3028(0x61, dev) < 0)
			return -EINVAL;
794
		break;
L
Linus Torvalds 已提交
795
	case CX88_BOARD_PCHDTV_HD3000:
796
		fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
797
					       &core->i2c_adap);
798 799
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
800 801 802
					&core->i2c_adap, 0x61,
					TUNER_THOMSON_DTT761X))
				goto frontend_detach;
803
		}
L
Linus Torvalds 已提交
804
		break;
805 806 807
	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
		dev->ts_gen_cntrl = 0x08;

808
		/* Do a hardware reset of chip before using it. */
809 810
		cx_clear(MO_GP0_IO, 1);
		mdelay(100);
811
		cx_set(MO_GP0_IO, 1);
812
		mdelay(200);
813 814

		/* Select RF connector callback */
815
		fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
816
		fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
817
					       &fusionhdtv_3_gold,
818
					       &core->i2c_adap);
819 820
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
821 822 823
					&core->i2c_adap, 0x61,
					TUNER_MICROTUNE_4042FI5))
				goto frontend_detach;
824 825
		}
		break;
826 827 828
	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
		dev->ts_gen_cntrl = 0x08;

829
		/* Do a hardware reset of chip before using it. */
830 831
		cx_clear(MO_GP0_IO, 1);
		mdelay(100);
M
Michael Krufky 已提交
832
		cx_set(MO_GP0_IO, 9);
833
		mdelay(200);
834
		fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
835
					       &fusionhdtv_3_gold,
836
					       &core->i2c_adap);
837 838
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
839 840 841
					&core->i2c_adap, 0x61,
					TUNER_THOMSON_DTT761X))
				goto frontend_detach;
842 843
		}
		break;
844 845 846
	case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
		dev->ts_gen_cntrl = 0x08;

847
		/* Do a hardware reset of chip before using it. */
848 849 850 851
		cx_clear(MO_GP0_IO, 1);
		mdelay(100);
		cx_set(MO_GP0_IO, 1);
		mdelay(200);
852
		fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
853
					       &fusionhdtv_5_gold,
854
					       &core->i2c_adap);
855 856
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
857 858 859
					&core->i2c_adap, 0x61,
					TUNER_LG_TDVS_H06XF))
				goto frontend_detach;
860
			if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
861 862
				   &core->i2c_adap, 0x43))
				goto frontend_detach;
863 864
		}
		break;
865 866 867
	case CX88_BOARD_PCHDTV_HD5500:
		dev->ts_gen_cntrl = 0x08;

868
		/* Do a hardware reset of chip before using it. */
869 870 871 872
		cx_clear(MO_GP0_IO, 1);
		mdelay(100);
		cx_set(MO_GP0_IO, 1);
		mdelay(200);
873
		fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
874
					       &pchdtv_hd5500,
875
					       &core->i2c_adap);
876 877
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
878 879 880
					&core->i2c_adap, 0x61,
					TUNER_LG_TDVS_H06XF))
				goto frontend_detach;
881
			if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
882 883
				   &core->i2c_adap, 0x43))
				goto frontend_detach;
884 885
		}
		break;
886
	case CX88_BOARD_ATI_HDTVWONDER:
887
		fe0->dvb.frontend = dvb_attach(nxt200x_attach,
888
					       &ati_hdtvwonder,
889
					       &core->i2c_adap);
890 891
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
892 893 894
					&core->i2c_adap, 0x61,
					TUNER_PHILIPS_TUV1236D))
				goto frontend_detach;
895
		}
896 897 898
		break;
	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
899
		fe0->dvb.frontend = dvb_attach(cx24123_attach,
900
					       &hauppauge_novas_config,
901
					       &core->i2c_adap);
902 903
		if (fe0->dvb.frontend) {
			if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
904
					&core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
905
				goto frontend_detach;
906
		}
907 908
		break;
	case CX88_BOARD_KWORLD_DVBS_100:
909
		fe0->dvb.frontend = dvb_attach(cx24123_attach,
910
					       &kworld_dvbs_100_config,
911
					       &core->i2c_adap);
912 913 914
		if (fe0->dvb.frontend) {
			core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
			fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
915
		}
916
		break;
917
	case CX88_BOARD_GENIATECH_DVBS:
918
		fe0->dvb.frontend = dvb_attach(cx24123_attach,
919
					       &geniatech_dvbs_config,
920
					       &core->i2c_adap);
921 922 923
		if (fe0->dvb.frontend) {
			core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
			fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
924 925
		}
		break;
926
	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
927
		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
928
					       &pinnacle_pctv_hd_800i_config,
929
					       &core->i2c_adap);
930 931
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
932
					&core->i2c_adap,
933
					&pinnacle_pctv_hd_800i_tuner_config))
934
				goto frontend_detach;
935 936
		}
		break;
937
	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
938
		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
939
						&dvico_hdtv5_pci_nano_config,
940
						&core->i2c_adap);
941
		if (fe0->dvb.frontend != NULL) {
942 943
			struct dvb_frontend *fe;
			struct xc2028_config cfg = {
944
				.i2c_adap  = &core->i2c_adap,
945 946 947
				.i2c_addr  = 0x61,
			};
			static struct xc2028_ctrl ctl = {
948
				.fname       = XC2028_DEFAULT_FIRMWARE,
949
				.max_len     = 64,
950
				.scode_table = XC3028_FE_OREN538,
951 952 953
			};

			fe = dvb_attach(xc2028_attach,
954
					fe0->dvb.frontend, &cfg);
955 956 957 958
			if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
				fe->ops.tuner_ops.set_config(fe, &ctl);
		}
		break;
959
	 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
960
		fe0->dvb.frontend = dvb_attach(zl10353_attach,
961
					       &cx88_pinnacle_hybrid_pctv,
962
					       &core->i2c_adap);
963 964
		if (fe0->dvb.frontend) {
			fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
965 966 967
			if (attach_xc3028(0x61, dev) < 0)
				goto frontend_detach;
		}
968 969
		break;
	 case CX88_BOARD_GENIATECH_X8000_MT:
970
		dev->ts_gen_cntrl = 0x00;
971

972
		fe0->dvb.frontend = dvb_attach(zl10353_attach,
973
					       &cx88_geniatech_x8000_mt,
974
					       &core->i2c_adap);
975
		if (attach_xc3028(0x61, dev) < 0)
976
			goto frontend_detach;
977
		break;
978
	 case CX88_BOARD_KWORLD_ATSC_120:
979
		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
980
					       &kworld_atsc_120_config,
981
					       &core->i2c_adap);
982
		if (attach_xc3028(0x61, dev) < 0)
983
			goto frontend_detach;
984
		break;
985
	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
986
		fe0->dvb.frontend = dvb_attach(s5h1411_attach,
987
					       &dvico_fusionhdtv7_config,
988
					       &core->i2c_adap);
989 990
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
991
					&core->i2c_adap,
992
					&dvico_fusionhdtv7_tuner_config))
993
				goto frontend_detach;
994 995
		}
		break;
996
	case CX88_BOARD_HAUPPAUGE_HVR4000:
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
		/* DVB-S/S2 Init */
		fe0->dvb.frontend = dvb_attach(cx24116_attach,
			&hauppauge_hvr4000_config,
			&dev->core->i2c_adap);
		if (fe0->dvb.frontend) {
			if(!dvb_attach(isl6421_attach, fe0->dvb.frontend,
				&dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
				dprintk( 1, "%s(): HVR4000 - DVB-S LNB Init: failed\n", __FUNCTION__);
			}
		} else {
			dprintk( 1, "%s(): HVR4000 - DVB-S Init: failed\n", __FUNCTION__);
		}
		/* DVB-T Init */
		fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
		if (fe1) {
			fe1->dvb.frontend = dvb_attach(cx22702_attach,
				&hauppauge_hvr_config,
				&dev->core->i2c_adap);
			if (fe1->dvb.frontend) {
				fe1->dvb.frontend->id = 1;
				if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
					&dev->core->i2c_adap, 0x61,
					TUNER_PHILIPS_FMD1216ME_MK3)) {
					dprintk( 1, "%s(): HVR4000 - DVB-T misc Init: failed\n", __FUNCTION__);
				}
			} else {
				dprintk( 1, "%s(): HVR4000 - DVB-T Init: failed\n", __FUNCTION__);
			}
		} else {
			dprintk( 1, "%s(): HVR4000 - DVB-T Init: can't find frontend 2.\n", __FUNCTION__);
		}
		break;
1029
	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
1030
		fe0->dvb.frontend = dvb_attach(cx24116_attach,
1031 1032
			&hauppauge_hvr4000_config,
			&dev->core->i2c_adap);
1033 1034
		if (fe0->dvb.frontend) {
			dvb_attach(isl6421_attach, fe0->dvb.frontend,
1035
				&dev->core->i2c_adap,
1036
				0x08, ISL6421_DCL, 0x00);
1037 1038
		}
		break;
1039
	case CX88_BOARD_TEVII_S420:
1040
		fe0->dvb.frontend = dvb_attach(stv0299_attach,
1041 1042
						&tevii_tuner_sharp_config,
						&core->i2c_adap);
1043 1044
		if (fe0->dvb.frontend != NULL) {
			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
1045 1046
					&core->i2c_adap, DVB_PLL_OPERA1))
				goto frontend_detach;
1047 1048
			core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
			fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1049 1050

		} else {
1051
			fe0->dvb.frontend = dvb_attach(stv0288_attach,
1052 1053
							    &tevii_tuner_earda_config,
							    &core->i2c_adap);
1054 1055
				if (fe0->dvb.frontend != NULL) {
					if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
1056 1057
						&core->i2c_adap))
					goto frontend_detach;
1058 1059
				core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
				fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1060 1061 1062 1063

			}
		}
		break;
1064
	case CX88_BOARD_TEVII_S460:
1065
		fe0->dvb.frontend = dvb_attach(cx24116_attach,
1066 1067
					       &tevii_s460_config,
					       &core->i2c_adap);
1068 1069 1070
		if (fe0->dvb.frontend != NULL) {
			core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
			fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1071 1072 1073
		}
		break;
	case CX88_BOARD_OMICOM_SS4_PCI:
1074
	case CX88_BOARD_TBS_8920:
1075
	case CX88_BOARD_PROF_7300:
1076
		fe0->dvb.frontend = dvb_attach(cx24116_attach,
1077 1078
					       &hauppauge_hvr4000_config,
					       &core->i2c_adap);
1079 1080 1081
		if (fe0->dvb.frontend != NULL) {
			core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
			fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1082 1083
		}
		break;
L
Linus Torvalds 已提交
1084
	default:
1085
		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1086
		       core->name);
L
Linus Torvalds 已提交
1087 1088
		break;
	}
1089 1090

        if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
1091 1092
		printk(KERN_ERR
		       "%s/2: frontend initialization failed\n",
1093
		       core->name);
1094
		return -EINVAL;
1095
	}
1096
	/* define general-purpose callback pointer */
1097
	fe0->dvb.frontend->callback = cx88_tuner_callback;
1098

1099
	/* Ensure all frontends negotiate bus access */
1100 1101 1102
	fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
	if (fe1)
		fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
L
Linus Torvalds 已提交
1103

1104
	/* Put the analog decoder in standby to keep it quiet */
1105
	cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
1106

L
Linus Torvalds 已提交
1107
	/* register everything */
1108 1109
	return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
		&dev->pci->dev, adapter_nr);
1110 1111

frontend_detach:
1112 1113 1114
	if (fe0->dvb.frontend) {
		dvb_frontend_detach(fe0->dvb.frontend);
		fe0->dvb.frontend = NULL;
1115 1116
	}
	return -EINVAL;
L
Linus Torvalds 已提交
1117 1118 1119 1120
}

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

1121 1122
/* CX8802 MPEG -> mini driver - We have been given the hardware */
static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
L
Linus Torvalds 已提交
1123
{
1124 1125
	struct cx88_core *core = drv->core;
	int err = 0;
1126
	dprintk( 1, "%s\n", __func__);
1127

1128
	switch (core->boardnr) {
1129 1130 1131 1132 1133 1134 1135 1136 1137
	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;
1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197

	case CX88_BOARD_HAUPPAUGE_HVR3000: /* ? */
		if(core->dvbdev->frontends.active_fe_id == 1) {
			/* DVB-S/S2 Enabled */

			/* Toggle reset on cx22702 leaving i2c active */
			cx_write(MO_GP0_IO, core->board.input[0].gpio0);
			udelay(1000);
			cx_clear(MO_GP0_IO, 0x00000080);
			udelay(50);
			cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */
			cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */
			udelay(1000);

			cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */
			core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
		} else
		if (core->dvbdev->frontends.active_fe_id == 2) {
			/* DVB-T Enabled */

			/* Put the cx24116/cx24123 into reset */
			cx_write(MO_SRST_IO, 0);

			/* cx22702 out of reset and enable it */
			cx_set(MO_GP0_IO,   0x00000080);
			cx_clear(MO_GP0_IO, 0x00000004);
			core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
			udelay(1000);
		}
		break;
	case CX88_BOARD_HAUPPAUGE_HVR4000:
		if(core->dvbdev->frontends.active_fe_id == 1) {
			/* DVB-S/S2 Enabled */

			/* Toggle reset on cx22702 leaving i2c active */
			cx_write(MO_GP0_IO, (core->board.input[0].gpio0 & 0x0000ff00) | 0x00000080);
			udelay(1000);
			cx_clear(MO_GP0_IO, 0x00000080);
			udelay(50);
			cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */
			cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */
			udelay(1000);

			cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */
			core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
		} else
		if (core->dvbdev->frontends.active_fe_id == 2) {
			/* DVB-T Enabled */

			/* Put the cx24116/cx24123 into reset */
			cx_write(MO_SRST_IO, 0);

			/* cx22702 out of reset and enable it */
			cx_set(MO_GP0_IO,   0x00000080);
			cx_clear(MO_GP0_IO, 0x00000004);
			core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
			udelay(1000);
		}
		break;

1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
	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;
1209
	dprintk( 1, "%s\n", __func__);
1210

1211
	switch (core->boardnr) {
1212 1213 1214
	case CX88_BOARD_HAUPPAUGE_HVR1300:
		/* Do Nothing, leave the cx22702 on the bus. */
		break;
1215 1216 1217
	case CX88_BOARD_HAUPPAUGE_HVR3000:
	case CX88_BOARD_HAUPPAUGE_HVR4000:
		break;
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
	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;
1228 1229
	int err,i;
	struct videobuf_dvb_frontend *fe;
L
Linus Torvalds 已提交
1230

1231
	dprintk( 1, "%s\n", __func__);
1232
	dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1233
		core->boardnr,
1234 1235 1236
		core->name,
		core->pci_bus,
		core->pci_slot);
L
Linus Torvalds 已提交
1237 1238

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

1242
	/* If vp3054 isn't enabled, a stub will just return 0 */
1243 1244
	err = vp3054_i2c_probe(dev);
	if (0 != err)
1245
		goto fail_core;
1246

L
Linus Torvalds 已提交
1247
	/* dvb stuff */
1248
	printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1249 1250 1251 1252 1253 1254 1255 1256 1257
	dev->ts_gen_cntrl = 0x0c;

	for (i = 1; i <= core->board.num_frontends; i++) {
		fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
		if (!fe) {
			printk(KERN_ERR "%s() failed to get frontend(%d)\n", __FUNCTION__, i);
			continue;
		}
		videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
1258
			    &dev->pci->dev, &dev->slock,
L
Linus Torvalds 已提交
1259 1260 1261 1262
			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
			    V4L2_FIELD_TOP,
			    sizeof(struct cx88_buffer),
			    dev);
1263 1264 1265
		/* init struct videobuf_dvb */
		fe->dvb.name = dev->core->name;
	}
L
Linus Torvalds 已提交
1266
	err = dvb_register(dev);
1267
	if (err != 0)
1268 1269
		printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
		       core->name, err);
L
Linus Torvalds 已提交
1270 1271 1272 1273 1274

 fail_core:
	return err;
}

1275
static int cx8802_dvb_remove(struct cx8802_driver *drv)
L
Linus Torvalds 已提交
1276
{
1277
	struct cx8802_dev *dev = drv->core->dvbdev;
1278

1279
	videobuf_dvb_unregister_bus(&dev->frontends);
L
Linus Torvalds 已提交
1280

1281 1282
	vp3054_i2c_remove(dev);

1283
	return 0;
L
Linus Torvalds 已提交
1284 1285
}

1286 1287 1288 1289 1290 1291 1292
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 已提交
1293 1294 1295 1296
};

static int dvb_init(void)
{
1297
	printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n",
L
Linus Torvalds 已提交
1298 1299 1300 1301 1302 1303 1304
	       (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
1305
	return cx8802_register_driver(&cx8802_dvb_driver);
L
Linus Torvalds 已提交
1306 1307 1308 1309
}

static void dvb_fini(void)
{
1310
	cx8802_unregister_driver(&cx8802_dvb_driver);
L
Linus Torvalds 已提交
1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321
}

module_init(dvb_init);
module_exit(dvb_fini);

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