dvb-bt8xx.c 27.2 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Bt8xx based DVB adapter driver
 *
 * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
 *
 * 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.
 *
 */

22 23
#define pr_fmt(fmt) "dvb_bt8xx: " fmt

L
Linus Torvalds 已提交
24 25 26
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/init.h>
27
#include <linux/kernel.h>
L
Linus Torvalds 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/i2c.h>

#include "dmxdev.h"
#include "dvbdev.h"
#include "dvb_demux.h"
#include "dvb_frontend.h"
#include "dvb-bt8xx.h"
#include "bt878.h"

static int debug;

module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");

45 46
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);

L
Linus Torvalds 已提交
47
#define dprintk( args... ) \
48
	do { \
L
Linus Torvalds 已提交
49
		if (debug) printk(KERN_DEBUG args); \
50
	} while (0)
L
Linus Torvalds 已提交
51

52 53
#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */

L
Linus Torvalds 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
static void dvb_bt8xx_task(unsigned long data)
{
	struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;

	//printk("%d ", card->bt->finished_block);

	while (card->bt->last_block != card->bt->finished_block) {
		(card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
			(&card->demux,
			 &card->bt->buf_cpu[card->bt->last_block *
					    card->bt->block_bytes],
			 card->bt->block_bytes);
		card->bt->last_block = (card->bt->last_block + 1) %
					card->bt->block_count;
	}
}

static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
73
	struct dvb_demux*dvbdmx = dvbdmxfeed->demux;
L
Linus Torvalds 已提交
74 75 76 77 78 79 80 81
	struct dvb_bt8xx_card *card = dvbdmx->priv;
	int rc;

	dprintk("dvb_bt8xx: start_feed\n");

	if (!dvbdmx->dmx.frontend)
		return -EINVAL;

82
	mutex_lock(&card->lock);
L
Linus Torvalds 已提交
83 84 85 86 87
	card->nfeeds++;
	rc = card->nfeeds;
	if (card->nfeeds == 1)
		bt878_start(card->bt, card->gpio_mode,
			    card->op_sync_orin, card->irq_err_ignore);
88
	mutex_unlock(&card->lock);
L
Linus Torvalds 已提交
89 90 91 92 93 94 95 96 97 98 99 100 101
	return rc;
}

static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
{
	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
	struct dvb_bt8xx_card *card = dvbdmx->priv;

	dprintk("dvb_bt8xx: stop_feed\n");

	if (!dvbdmx->dmx.frontend)
		return -EINVAL;

102
	mutex_lock(&card->lock);
L
Linus Torvalds 已提交
103 104 105
	card->nfeeds--;
	if (card->nfeeds == 0)
		bt878_stop(card->bt);
106
	mutex_unlock(&card->lock);
L
Linus Torvalds 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120

	return 0;
}

static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
{
	if ((adev->subsystem_vendor == bdev->subsystem_vendor) &&
		(adev->subsystem_device == bdev->subsystem_device) &&
		(adev->bus->number == bdev->bus->number) &&
		(PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn)))
		return 1;
	return 0;
}

121
static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
L
Linus Torvalds 已提交
122 123 124 125
{
	unsigned int card_nr;

	/* Hmm, n squared. Hope n is small */
D
David Johnson 已提交
126
	for (card_nr = 0; card_nr < bt878_num; card_nr++)
L
Linus Torvalds 已提交
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
		if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
			return &bt878[card_nr];
	return NULL;
}

static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
{
	static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 };
	static u8 mt352_reset [] = { 0x50, 0x80 };
	static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
	static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0x20 };
	static u8 mt352_gpp_ctl_cfg [] = { 0x8C, 0x33 };
	static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };

	mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
	udelay(2000);
	mt352_write(fe, mt352_reset, sizeof(mt352_reset));
	mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));

	mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
147
	mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
L
Linus Torvalds 已提交
148 149 150 151 152
	mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));

	return 0;
}

153
static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend *fe, u8* pllbuf, int buf_len)
L
Linus Torvalds 已提交
154
{
155
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
L
Linus Torvalds 已提交
156 157 158 159
	u32 div;
	unsigned char bs = 0;
	unsigned char cp = 0;

160 161 162
	if (buf_len < 5)
		return -EINVAL;

163
	div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
L
Linus Torvalds 已提交
164

165
	if (c->frequency < 542000000)
D
David Johnson 已提交
166
		cp = 0xb4;
167
	else if (c->frequency < 771000000)
D
David Johnson 已提交
168 169 170
		cp = 0xbc;
	else
		cp = 0xf4;
L
Linus Torvalds 已提交
171

172
	if (c->frequency == 0)
D
David Johnson 已提交
173
		bs = 0x03;
174
	else if (c->frequency < 443250000)
D
David Johnson 已提交
175 176 177
		bs = 0x02;
	else
		bs = 0x08;
L
Linus Torvalds 已提交
178

179
	pllbuf[0] = 0x60;
L
Linus Torvalds 已提交
180 181 182 183 184
	pllbuf[1] = div >> 8;
	pllbuf[2] = div & 0xff;
	pllbuf[3] = cp;
	pllbuf[4] = bs;

185
	return 5;
L
Linus Torvalds 已提交
186 187 188 189 190 191 192
}

static struct mt352_config thomson_dtt7579_config = {
	.demod_address = 0x0f,
	.demod_init = thomson_dtt7579_demod_init,
};

193 194 195 196
static struct zl10353_config thomson_dtt7579_zl10353_config = {
	.demod_address = 0x0f,
};

197
static int cx24108_tuner_set_params(struct dvb_frontend *fe)
L
Linus Torvalds 已提交
198
{
199 200
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	u32 freq = c->frequency;
D
David Johnson 已提交
201 202 203 204 205 206 207
	int i, a, n, pump;
	u32 band, pll;
	u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
		1576000,1718000,1856000,2036000,2150000};
	u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
		0x00102000,0x00104000,0x00108000,0x00110000,
		0x00120000,0x00140000};
L
Linus Torvalds 已提交
208

D
David Johnson 已提交
209
	#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
210
	dprintk("cx24108 debug: entering SetTunerFreq, freq=%d\n", freq);
211 212 213

	/* This is really the bit driving the tuner chip cx24108 */

D
David Johnson 已提交
214 215 216 217
	if (freq<950000)
		freq = 950000; /* kHz */
	else if (freq>2150000)
		freq = 2150000; /* satellite IF is 950..2150MHz */
218 219

	/* decide which VCO to use for the input frequency */
220
	for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++);
221
	dprintk("cx24108 debug: select vco #%d (f=%d)\n", i, freq);
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
	band=bandsel[i];
	/* the gain values must be set by SetSymbolrate */
	/* compute the pll divider needed, from Conexant data sheet,
	   resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
	   depending on the divider bit. It is set to /4 on the 2 lowest
	   bands  */
	n=((i<=2?2:1)*freq*10L)/(XTAL/100);
	a=n%32; n/=32; if(a==0) n--;
	pump=(freq<(osci[i-1]+osci[i])/2);
	pll=0xf8000000|
	    ((pump?1:2)<<(14+11))|
	    ((n&0x1ff)<<(5+11))|
	    ((a&0x1f)<<11);
	/* everything is shifted left 11 bits to left-align the bits in the
	   32bit word. Output to the tuner goes MSB-aligned, after all */
237
	dprintk("cx24108 debug: pump=%d, n=%d, a=%d\n", pump, n, a);
238 239 240 241 242 243
	cx24110_pll_write(fe,band);
	/* set vga and vca to their widest-band settings, as a precaution.
	   SetSymbolrate might not be called to set this up */
	cx24110_pll_write(fe,0x500c0000);
	cx24110_pll_write(fe,0x83f1f800);
	cx24110_pll_write(fe,pll);
D
David Johnson 已提交
244
	//writereg(client,0x56,0x7f);
L
Linus Torvalds 已提交
245 246 247 248

	return 0;
}

249
static int pinnsat_tuner_init(struct dvb_frontend* fe)
L
Linus Torvalds 已提交
250
{
251 252 253 254
	struct dvb_bt8xx_card *card = fe->dvb->priv;

	bttv_gpio_enable(card->bttv_nr, 1, 1);  /* output */
	bttv_write_gpio(card->bttv_nr, 1, 1);   /* relay on */
255

256 257 258
	return 0;
}

259
static int pinnsat_tuner_sleep(struct dvb_frontend* fe)
260 261 262 263 264
{
	struct dvb_bt8xx_card *card = fe->dvb->priv;

	bttv_write_gpio(card->bttv_nr, 1, 0);   /* relay off */

D
David Johnson 已提交
265
	return 0;
L
Linus Torvalds 已提交
266 267 268 269 270 271
}

static struct cx24110_config pctvsat_config = {
	.demod_address = 0x55,
};

272
static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend *fe)
L
Linus Torvalds 已提交
273
{
274
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
L
Linus Torvalds 已提交
275 276 277 278 279 280
	struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
	u8 cfg, cpump, band_select;
	u8 data[4];
	u32 div;
	struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };

281
	div = (36000000 + c->frequency + 83333) / 166666;
L
Linus Torvalds 已提交
282 283
	cfg = 0x88;

284
	if (c->frequency < 175000000)
D
David Johnson 已提交
285
		cpump = 2;
286
	else if (c->frequency < 390000000)
D
David Johnson 已提交
287
		cpump = 1;
288
	else if (c->frequency < 470000000)
D
David Johnson 已提交
289
		cpump = 2;
290
	else if (c->frequency < 750000000)
D
David Johnson 已提交
291 292 293
		cpump = 2;
	else
		cpump = 3;
L
Linus Torvalds 已提交
294

295
	if (c->frequency < 175000000)
D
David Johnson 已提交
296
		band_select = 0x0e;
297
	else if (c->frequency < 470000000)
D
David Johnson 已提交
298 299 300
		band_select = 0x05;
	else
		band_select = 0x03;
L
Linus Torvalds 已提交
301 302 303 304

	data[0] = (div >> 8) & 0x7f;
	data[1] = div & 0xff;
	data[2] = ((div >> 10) & 0x60) | cfg;
305
	data[3] = (cpump << 6) | band_select;
L
Linus Torvalds 已提交
306

307 308
	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);
L
Linus Torvalds 已提交
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
	i2c_transfer(card->i2c_adapter, &msg, 1);
	return (div * 166666 - 36000000);
}

static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
{
	struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;

	return request_firmware(fw, name, &bt->bt->dev->dev);
}

static struct sp887x_config microtune_mt7202dtf_config = {
	.demod_address = 0x70,
	.request_firmware = microtune_mt7202dtf_request_firmware,
};

static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
{
	static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
	static u8 mt352_reset [] = { 0x50, 0x80 };
	static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
	static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
331
				       0x00, 0xFF, 0x00, 0x40, 0x40 };
L
Linus Torvalds 已提交
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
	static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
	static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };

	mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
	udelay(2000);
	mt352_write(fe, mt352_reset, sizeof(mt352_reset));
	mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));

	mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
	udelay(2000);
	mt352_write(fe, mt352_av771_extra,sizeof(mt352_av771_extra));
	mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));

	return 0;
}

348
static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend *fe, u8 *pllbuf, int buf_len)
L
Linus Torvalds 已提交
349
{
350
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
L
Linus Torvalds 已提交
351 352 353 354
	u32 div;
	unsigned char bs = 0;
	unsigned char cp = 0;

355 356
	if (buf_len < 5) return -EINVAL;

357
	div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
L
Linus Torvalds 已提交
358

359
	if (c->frequency < 150000000)
D
David Johnson 已提交
360
		cp = 0xB4;
361
	else if (c->frequency < 173000000)
D
David Johnson 已提交
362
		cp = 0xBC;
363
	else if (c->frequency < 250000000)
D
David Johnson 已提交
364
		cp = 0xB4;
365
	else if (c->frequency < 400000000)
D
David Johnson 已提交
366
		cp = 0xBC;
367
	else if (c->frequency < 420000000)
D
David Johnson 已提交
368
		cp = 0xF4;
369
	else if (c->frequency < 470000000)
D
David Johnson 已提交
370
		cp = 0xFC;
371
	else if (c->frequency < 600000000)
D
David Johnson 已提交
372
		cp = 0xBC;
373
	else if (c->frequency < 730000000)
D
David Johnson 已提交
374 375 376 377
		cp = 0xF4;
	else
		cp = 0xFC;

378
	if (c->frequency < 150000000)
D
David Johnson 已提交
379
		bs = 0x01;
380
	else if (c->frequency < 173000000)
D
David Johnson 已提交
381
		bs = 0x01;
382
	else if (c->frequency < 250000000)
D
David Johnson 已提交
383
		bs = 0x02;
384
	else if (c->frequency < 400000000)
D
David Johnson 已提交
385
		bs = 0x02;
386
	else if (c->frequency < 420000000)
D
David Johnson 已提交
387
		bs = 0x02;
388
	else if (c->frequency < 470000000)
D
David Johnson 已提交
389
		bs = 0x02;
390
	else if (c->frequency < 600000000)
D
David Johnson 已提交
391
		bs = 0x08;
392
	else if (c->frequency < 730000000)
D
David Johnson 已提交
393 394 395
		bs = 0x08;
	else
		bs = 0x08;
L
Linus Torvalds 已提交
396

397
	pllbuf[0] = 0x61;
L
Linus Torvalds 已提交
398 399 400 401 402
	pllbuf[1] = div >> 8;
	pllbuf[2] = div & 0xff;
	pllbuf[3] = cp;
	pllbuf[4] = bs;

403
	return 5;
L
Linus Torvalds 已提交
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
}

static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
	.demod_address = 0x0f,
	.demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
};

static struct dst_config dst_config = {
	.demod_address = 0x55,
};

static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
{
	struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;

	return request_firmware(fw, name, &bt->bt->dev->dev);
}

static void or51211_setmode(struct dvb_frontend * fe, int mode)
{
	struct dvb_bt8xx_card *bt = fe->dvb->priv;
	bttv_write_gpio(bt->bttv_nr, 0x0002, mode);   /* Reset */
	msleep(20);
}

static void or51211_reset(struct dvb_frontend * fe)
{
	struct dvb_bt8xx_card *bt = fe->dvb->priv;

	/* RESET DEVICE
L
Lucas De Marchi 已提交
434
	 * reset is controlled by GPIO-0
L
Linus Torvalds 已提交
435 436
	 * when set to 0 causes reset and when to 1 for normal op
	 * must remain reset for 128 clock cycles on a 50Mhz clock
L
Lucas De Marchi 已提交
437
	 * also PRM1 PRM2 & PRM4 are controlled by GPIO-1,GPIO-2 & GPIO-4
L
Linus Torvalds 已提交
438 439 440 441 442 443
	 * We assume that the reset has be held low long enough or we
	 * have been reset by a power on.  When the driver is unloaded
	 * reset set to 0 so if reloaded we have been reset.
	 */
	/* reset & PRM1,2&4 are outputs */
	int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
D
David Johnson 已提交
444
	if (ret != 0)
445
		printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret);
L
Linus Torvalds 已提交
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
	bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000);   /* Reset */
	msleep(20);
	/* Now set for normal operation */
	bttv_write_gpio(bt->bttv_nr, 0x0001F, 0x0001);
	/* wait for operation to begin */
	msleep(500);
}

static void or51211_sleep(struct dvb_frontend * fe)
{
	struct dvb_bt8xx_card *bt = fe->dvb->priv;
	bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000);
}

static struct or51211_config or51211_config = {
	.demod_address = 0x15,
	.request_firmware = or51211_request_firmware,
	.setmode = or51211_setmode,
	.reset = or51211_reset,
	.sleep = or51211_sleep,
};

468
static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend *fe)
L
Linus Torvalds 已提交
469
{
470
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
L
Linus Torvalds 已提交
471 472 473 474 475
	struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
	u8 buf[4];
	u32 div;
	struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) };

476
	div = (c->frequency + 36166667) / 166667;
L
Linus Torvalds 已提交
477 478 479 480

	buf[0] = (div >> 8) & 0x7F;
	buf[1] = div & 0xFF;
	buf[2] = 0x85;
481
	if ((c->frequency >= 47000000) && (c->frequency < 153000000))
L
Linus Torvalds 已提交
482
		buf[3] = 0x01;
483
	else if ((c->frequency >= 153000000) && (c->frequency < 430000000))
L
Linus Torvalds 已提交
484
		buf[3] = 0x02;
485
	else if ((c->frequency >= 430000000) && (c->frequency < 824000000))
L
Linus Torvalds 已提交
486
		buf[3] = 0x0C;
487
	else if ((c->frequency >= 824000000) && (c->frequency < 863000000))
L
Linus Torvalds 已提交
488 489 490 491
		buf[3] = 0x8C;
	else
		return -EINVAL;

492 493
	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);
L
Linus Torvalds 已提交
494 495 496 497 498 499 500 501 502
	i2c_transfer(card->i2c_adapter, &msg, 1);
	return 0;
}

static struct nxt6000_config vp3021_alps_tded4_config = {
	.demod_address = 0x0a,
	.clock_inversion = 1,
};

503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
{
	static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
	static u8 mt352_reset [] = { 0x50, 0x80 };
	static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
	static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 };
	static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };

	mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
	udelay(2000);
	mt352_write(fe, mt352_reset, sizeof(mt352_reset));
	mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
	mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
	mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));

	return 0;
}

521
static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend *fe,  u8 *pllbuf, int buf_len)
522 523
{
	u32 div;
524
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
525

526 527 528
	if (buf_len < 5)
		return -EINVAL;

529
	div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
530

531
	pllbuf[0] = 0x61;
532 533 534 535
	pllbuf[1] = (div >> 8) & 0x7F;
	pllbuf[2] = div & 0xFF;
	pllbuf[3] = 0x85;

536
	dprintk("frequency %u, div %u\n", c->frequency, div);
537

538
	if (c->frequency < 470000000)
539
		pllbuf[4] = 0x02;
540
	else if (c->frequency > 823000000)
541 542 543 544
		pllbuf[4] = 0x88;
	else
		pllbuf[4] = 0x08;

545
	if (c->bandwidth_hz == 8000000)
546 547
		pllbuf[4] |= 0x04;

548
	return 5;
549 550 551 552 553 554 555
}

static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
{
	/*
	 * Reset the frontend, must be called before trying
	 * to initialise the MT352 or mt352_attach
556
	 * will fail. Same goes for the nxt6000 frontend.
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
	 *
	 */

	int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08);
	if (ret != 0)
		printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret);

	/* Pulse the reset line */
	bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
	bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low  */
	msleep(100);

	bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
}

static struct mt352_config digitv_alps_tded4_config = {
	.demod_address = 0x0a,
	.demod_init = digitv_alps_tded4_demod_init,
};

577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
static struct lgdt330x_config tdvs_tua6034_config = {
	.demod_address    = 0x0e,
	.demod_chip       = LGDT3303,
	.serial_mpeg      = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
};

static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
{
	/* Set pin 27 of the lgdt3303 chip high to reset the frontend */

	/* Pulse the reset line */
	bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
	bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low  */
	msleep(100);

	bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
	msleep(100);
}

L
Linus Torvalds 已提交
596 597
static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
{
598 599
	struct dst_state* state = NULL;

L
Linus Torvalds 已提交
600
	switch(type) {
601
	case BTTV_BOARD_DVICO_DVBT_LITE:
602
		card->fe = dvb_attach(mt352_attach, &thomson_dtt7579_config, card->i2c_adapter);
603 604

		if (card->fe == NULL)
605
			card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config,
606 607
						  card->i2c_adapter);

L
Linus Torvalds 已提交
608
		if (card->fe != NULL) {
609 610 611
			card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs;
			card->fe->ops.info.frequency_min = 174000000;
			card->fe->ops.info.frequency_max = 862000000;
L
Linus Torvalds 已提交
612 613 614
		}
		break;

615
	case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
616
		lgdt330x_reset(card);
617
		card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
618
		if (card->fe != NULL) {
619 620 621
			dvb_attach(simple_tuner_attach, card->fe,
				   card->i2c_adapter, 0x61,
				   TUNER_LG_TDVS_H06XF);
622
			dprintk ("dvb_bt8xx: lgdt330x detected\n");
623
		}
624 625
		break;

626
	case BTTV_BOARD_NEBULA_DIGITV:
627 628 629 630 631 632
		/*
		 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
		 * this would be a cleaner solution than trying each frontend in turn.
		 */

		/* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
633
		digitv_alps_tded4_reset(card);
634
		card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter);
635
		if (card->fe != NULL) {
636
			card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params;
637
			dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
638 639
			break;
		}
640 641 642

		/* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
		digitv_alps_tded4_reset(card);
643
		card->fe = dvb_attach(mt352_attach, &digitv_alps_tded4_config, card->i2c_adapter);
644

645
		if (card->fe != NULL) {
646
			card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs;
647
			dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
648
		}
L
Linus Torvalds 已提交
649 650
		break;

651
	case BTTV_BOARD_AVDVBT_761:
652
		card->fe = dvb_attach(sp887x_attach, &microtune_mt7202dtf_config, card->i2c_adapter);
653
		if (card->fe) {
654
			card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params;
655
		}
L
Linus Torvalds 已提交
656 657
		break;

658
	case BTTV_BOARD_AVDVBT_771:
659
		card->fe = dvb_attach(mt352_attach, &advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
L
Linus Torvalds 已提交
660
		if (card->fe != NULL) {
661 662 663
			card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs;
			card->fe->ops.info.frequency_min = 174000000;
			card->fe->ops.info.frequency_max = 862000000;
L
Linus Torvalds 已提交
664 665 666
		}
		break;

667
	case BTTV_BOARD_TWINHAN_DST:
668
		/*	DST is not a frontend driver !!!		*/
669
		state = kmalloc(sizeof (struct dst_state), GFP_KERNEL);
670
		if (!state) {
671
			pr_err("No memory\n");
672 673
			break;
		}
674 675 676 677
		/*	Setup the Card					*/
		state->config = &dst_config;
		state->i2c = card->i2c_adapter;
		state->bt = card->bt;
678
		state->dst_ca = NULL;
679
		/*	DST is not a frontend, attaching the ASIC	*/
680
		if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) {
681
			pr_err("%s: Could not find a Twinhan DST\n", __func__);
682 683
			break;
		}
684 685
		/*	Attach other DST peripherals if any		*/
		/*	Conditional Access device			*/
686
		card->fe = &state->frontend;
687 688
		if (state->dst_hw_cap & DST_TYPE_HAS_CA)
			dvb_attach(dst_ca_attach, state, &card->dvb_adapter);
L
Linus Torvalds 已提交
689 690
		break;

691
	case BTTV_BOARD_PINNACLESAT:
692
		card->fe = dvb_attach(cx24110_attach, &pctvsat_config, card->i2c_adapter);
693
		if (card->fe) {
694 695 696
			card->fe->ops.tuner_ops.init = pinnsat_tuner_init;
			card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep;
			card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params;
697
		}
L
Linus Torvalds 已提交
698 699
		break;

700
	case BTTV_BOARD_PC_HDTV:
701
		card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter);
702
		if (card->fe != NULL)
703 704 705
			dvb_attach(simple_tuner_attach, card->fe,
				   card->i2c_adapter, 0x61,
				   TUNER_PHILIPS_FCV1236D);
L
Linus Torvalds 已提交
706 707 708
		break;
	}

D
David Johnson 已提交
709
	if (card->fe == NULL)
710
		pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
L
Linus Torvalds 已提交
711 712 713 714
		       card->bt->dev->vendor,
		       card->bt->dev->device,
		       card->bt->dev->subsystem_vendor,
		       card->bt->dev->subsystem_device);
D
David Johnson 已提交
715
	else
716
		if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
717
			pr_err("Frontend registration failed!\n");
718
			dvb_frontend_detach(card->fe);
L
Linus Torvalds 已提交
719 720 721 722
			card->fe = NULL;
		}
}

723
static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
L
Linus Torvalds 已提交
724 725 726
{
	int result;

727 728 729 730
	result = dvb_register_adapter(&card->dvb_adapter, card->card_name,
				      THIS_MODULE, &card->bt->dev->dev,
				      adapter_nr);
	if (result < 0) {
731
		pr_err("dvb_register_adapter failed (errno = %d)\n", result);
L
Linus Torvalds 已提交
732 733
		return result;
	}
734
	card->dvb_adapter.priv = card;
L
Linus Torvalds 已提交
735 736 737 738 739 740 741 742 743 744 745 746 747 748

	card->bt->adapter = card->i2c_adapter;

	memset(&card->demux, 0, sizeof(struct dvb_demux));

	card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;

	card->demux.priv = card;
	card->demux.filternum = 256;
	card->demux.feednum = 256;
	card->demux.start_feed = dvb_bt8xx_start_feed;
	card->demux.stop_feed = dvb_bt8xx_stop_feed;
	card->demux.write_to_decoder = NULL;

749 750
	result = dvb_dmx_init(&card->demux);
	if (result < 0) {
751
		pr_err("dvb_dmx_init failed (errno = %d)\n", result);
752
		goto err_unregister_adaptor;
L
Linus Torvalds 已提交
753 754 755 756 757 758
	}

	card->dmxdev.filternum = 256;
	card->dmxdev.demux = &card->demux.dmx;
	card->dmxdev.capabilities = 0;

759 760
	result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter);
	if (result < 0) {
761
		pr_err("dvb_dmxdev_init failed (errno = %d)\n", result);
762
		goto err_dmx_release;
L
Linus Torvalds 已提交
763 764 765 766
	}

	card->fe_hw.source = DMX_FRONTEND_0;

767 768
	result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw);
	if (result < 0) {
769
		pr_err("dvb_dmx_init failed (errno = %d)\n", result);
770
		goto err_dmxdev_release;
L
Linus Torvalds 已提交
771 772 773 774
	}

	card->fe_mem.source = DMX_MEMORY_FE;

775 776
	result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem);
	if (result < 0) {
777
		pr_err("dvb_dmx_init failed (errno = %d)\n", result);
778
		goto err_remove_hw_frontend;
L
Linus Torvalds 已提交
779 780
	}

781 782
	result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw);
	if (result < 0) {
783
		pr_err("dvb_dmx_init failed (errno = %d)\n", result);
784
		goto err_remove_mem_frontend;
L
Linus Torvalds 已提交
785 786
	}

787 788
	result = dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
	if (result < 0) {
789
		pr_err("dvb_net_init failed (errno = %d)\n", result);
790 791
		goto err_disconnect_frontend;
	}
L
Linus Torvalds 已提交
792 793 794 795 796 797

	tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);

	frontend_init(card, type);

	return 0;
798

799 800
err_disconnect_frontend:
	card->demux.dmx.disconnect_frontend(&card->demux.dmx);
801 802 803 804 805 806 807 808 809 810 811
err_remove_mem_frontend:
	card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
err_remove_hw_frontend:
	card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
err_dmxdev_release:
	dvb_dmxdev_release(&card->dmxdev);
err_dmx_release:
	dvb_dmx_release(&card->demux);
err_unregister_adaptor:
	dvb_unregister_adapter(&card->dvb_adapter);
	return result;
L
Linus Torvalds 已提交
812 813
}

814
static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub)
L
Linus Torvalds 已提交
815 816 817 818 819
{
	struct dvb_bt8xx_card *card;
	struct pci_dev* bttv_pci_dev;
	int ret;

P
 
Panagiotis Issaris 已提交
820
	if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
L
Linus Torvalds 已提交
821 822
		return -ENOMEM;

823
	mutex_init(&card->lock);
L
Linus Torvalds 已提交
824
	card->bttv_nr = sub->core->nr;
825
	strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name));
L
Linus Torvalds 已提交
826 827
	card->i2c_adapter = &sub->core->i2c_adap;

D
David Johnson 已提交
828
	switch(sub->core->type) {
829
	case BTTV_BOARD_PINNACLESAT:
L
Linus Torvalds 已提交
830 831
		card->gpio_mode = 0x0400c060;
		/* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
832
			      BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
833 834
		card->op_sync_orin = BT878_RISC_SYNC_MASK;
		card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
L
Linus Torvalds 已提交
835 836
		break;

837
	case BTTV_BOARD_DVICO_DVBT_LITE:
L
Linus Torvalds 已提交
838
		card->gpio_mode = 0x0400C060;
839 840
		card->op_sync_orin = BT878_RISC_SYNC_MASK;
		card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
L
Linus Torvalds 已提交
841 842 843 844 845
		/* 26, 15, 14, 6, 5
		 * A_PWRDN  DA_DPM DA_SBR DA_IOM_DA
		 * DA_APP(parallel) */
		break;

846
	case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
847 848 849 850 851
		card->gpio_mode = 0x0400c060;
		card->op_sync_orin = BT878_RISC_SYNC_MASK;
		card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
		break;

852 853
	case BTTV_BOARD_NEBULA_DIGITV:
	case BTTV_BOARD_AVDVBT_761:
L
Linus Torvalds 已提交
854
		card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
855 856
		card->op_sync_orin = BT878_RISC_SYNC_MASK;
		card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
L
Linus Torvalds 已提交
857 858 859
		/* A_PWRDN DA_SBR DA_APP (high speed serial) */
		break;

860
	case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
L
Linus Torvalds 已提交
861 862
		card->gpio_mode = 0x0400402B;
		card->op_sync_orin = BT878_RISC_SYNC_MASK;
863
		card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
L
Linus Torvalds 已提交
864 865 866
		/* A_PWRDN DA_SBR  DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
		break;

867
	case BTTV_BOARD_TWINHAN_DST:
L
Linus Torvalds 已提交
868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
		card->gpio_mode = 0x2204f2c;
		card->op_sync_orin = BT878_RISC_SYNC_MASK;
		card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
				       BT878_APPERR | BT878_AFBUS;
		/* 25,21,14,11,10,9,8,3,2 then
		 * 0x33 = 5,4,1,0
		 * A_SEL=SML, DA_MLB, DA_SBR,
		 * DA_SDR=f, fifo trigger = 32 DWORDS
		 * IOM = 0 == audio A/D
		 * DPM = 0 == digital audio mode
		 * == async data parallel port
		 * then 0x33 (13 is set by start_capture)
		 * DA_APP = async data parallel port,
		 * ACAP_EN = 1,
		 * RISC+FIFO ENABLE */
		break;

885
	case BTTV_BOARD_PC_HDTV:
L
Linus Torvalds 已提交
886
		card->gpio_mode = 0x0100EC7B;
887 888
		card->op_sync_orin = BT878_RISC_SYNC_MASK;
		card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
L
Linus Torvalds 已提交
889 890
		break;

891
	default:
892
		pr_err("Unknown bttv card type: %d\n", sub->core->type);
L
Linus Torvalds 已提交
893 894 895 896 897 898 899
		kfree(card);
		return -ENODEV;
	}

	dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name);

	if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) {
900
		pr_err("no pci device for card %d\n", card->bttv_nr);
L
Linus Torvalds 已提交
901
		kfree(card);
902
		return -ENODEV;
L
Linus Torvalds 已提交
903 904 905
	}

	if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) {
906 907
		pr_err("unable to determine DMA core of card %d,\n", card->bttv_nr);
		pr_err("if you have the ALSA bt87x audio driver installed, try removing it.\n");
L
Linus Torvalds 已提交
908 909

		kfree(card);
910
		return -ENODEV;
L
Linus Torvalds 已提交
911 912
	}

913
	mutex_init(&card->bt->gpio_lock);
L
Linus Torvalds 已提交
914 915 916 917 918 919 920
	card->bt->bttv_nr = sub->core->nr;

	if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) {
		kfree(card);
		return ret;
	}

921
	dev_set_drvdata(&sub->dev, card);
L
Linus Torvalds 已提交
922 923 924
	return 0;
}

925
static void dvb_bt8xx_remove(struct bttv_sub_device *sub)
L
Linus Torvalds 已提交
926
{
927
	struct dvb_bt8xx_card *card = dev_get_drvdata(&sub->dev);
L
Linus Torvalds 已提交
928 929 930 931 932 933 934 935 936 937

	dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);

	bt878_stop(card->bt);
	tasklet_kill(&card->bt->tasklet);
	dvb_net_release(&card->dvbnet);
	card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
	card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
	dvb_dmxdev_release(&card->dmxdev);
	dvb_dmx_release(&card->demux);
938
	if (card->fe) {
D
David Johnson 已提交
939
		dvb_unregister_frontend(card->fe);
940
		dvb_frontend_detach(card->fe);
941
	}
942
	dvb_unregister_adapter(&card->dvb_adapter);
L
Linus Torvalds 已提交
943 944 945 946 947 948 949 950

	kfree(card);
}

static struct bttv_sub_driver driver = {
	.drv = {
		.name		= "dvb-bt8xx",
	},
951 952 953 954 955 956 957
	.probe		= dvb_bt8xx_probe,
	.remove		= dvb_bt8xx_remove,
	/* FIXME:
	 * .shutdown	= dvb_bt8xx_shutdown,
	 * .suspend	= dvb_bt8xx_suspend,
	 * .resume	= dvb_bt8xx_resume,
	 */
L
Linus Torvalds 已提交
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975
};

static int __init dvb_bt8xx_init(void)
{
	return bttv_sub_register(&driver, "dvb");
}

static void __exit dvb_bt8xx_exit(void)
{
	bttv_sub_unregister(&driver);
}

module_init(dvb_bt8xx_init);
module_exit(dvb_bt8xx_exit);

MODULE_DESCRIPTION("Bt8xx based DVB adapter driver");
MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
MODULE_LICENSE("GPL");