PageRenderTime 82ms CodeModel.GetById 24ms app.highlight 45ms RepoModel.GetById 0ms app.codeStats 1ms

/drivers/media/dvb/ttpci/budget-av.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 1635 lines | 1320 code | 226 blank | 89 comment | 174 complexity | 6d7fcf3f2358f6e8ca3325c44fa1f9ae MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
   1/*
   2 * budget-av.c: driver for the SAA7146 based Budget DVB cards
   3 *              with analog video in
   4 *
   5 * Compiled from various sources by Michael Hunold <michael@mihu.de>
   6 *
   7 * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
   8 *                               Andrew de Quincey <adq_dvb@lidskialf.net>
   9 *
  10 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
  11 *
  12 * Copyright (C) 1999-2002 Ralph  Metzler
  13 *                       & Marcus Metzler for convergence integrated media GmbH
  14 *
  15 * This program is free software; you can redistribute it and/or
  16 * modify it under the terms of the GNU General Public License
  17 * as published by the Free Software Foundation; either version 2
  18 * of the License, or (at your option) any later version.
  19 *
  20 *
  21 * This program is distributed in the hope that it will be useful,
  22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24 * GNU General Public License for more details.
  25 *
  26 *
  27 * You should have received a copy of the GNU General Public License
  28 * along with this program; if not, write to the Free Software
  29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  30 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  31 *
  32 *
  33 * the project's page is at http://www.linuxtv.org/ 
  34 */
  35
  36#include "budget.h"
  37#include "stv0299.h"
  38#include "stb0899_drv.h"
  39#include "stb0899_reg.h"
  40#include "stb0899_cfg.h"
  41#include "tda8261.h"
  42#include "tda8261_cfg.h"
  43#include "tda1002x.h"
  44#include "tda1004x.h"
  45#include "tua6100.h"
  46#include "dvb-pll.h"
  47#include <media/saa7146_vv.h>
  48#include <linux/module.h>
  49#include <linux/errno.h>
  50#include <linux/slab.h>
  51#include <linux/interrupt.h>
  52#include <linux/input.h>
  53#include <linux/spinlock.h>
  54
  55#include "dvb_ca_en50221.h"
  56
  57#define DEBICICAM		0x02420000
  58
  59#define SLOTSTATUS_NONE         1
  60#define SLOTSTATUS_PRESENT      2
  61#define SLOTSTATUS_RESET        4
  62#define SLOTSTATUS_READY        8
  63#define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
  64
  65DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  66
  67struct budget_av {
  68	struct budget budget;
  69	struct video_device *vd;
  70	int cur_input;
  71	int has_saa7113;
  72	struct tasklet_struct ciintf_irq_tasklet;
  73	int slot_status;
  74	struct dvb_ca_en50221 ca;
  75	u8 reinitialise_demod:1;
  76};
  77
  78static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
  79
  80
  81/* GPIO Connections:
  82 * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
  83 * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
  84 * 2 - CI Card Enable (Active Low)
  85 * 3 - CI Card Detect
  86 */
  87
  88/****************************************************************************
  89 * INITIALIZATION
  90 ****************************************************************************/
  91
  92static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
  93{
  94	u8 mm1[] = { 0x00 };
  95	u8 mm2[] = { 0x00 };
  96	struct i2c_msg msgs[2];
  97
  98	msgs[0].flags = 0;
  99	msgs[1].flags = I2C_M_RD;
 100	msgs[0].addr = msgs[1].addr = id / 2;
 101	mm1[0] = reg;
 102	msgs[0].len = 1;
 103	msgs[1].len = 1;
 104	msgs[0].buf = mm1;
 105	msgs[1].buf = mm2;
 106
 107	i2c_transfer(i2c, msgs, 2);
 108
 109	return mm2[0];
 110}
 111
 112static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
 113{
 114	u8 mm1[] = { reg };
 115	struct i2c_msg msgs[2] = {
 116		{.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
 117		{.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
 118	};
 119
 120	if (i2c_transfer(i2c, msgs, 2) != 2)
 121		return -EIO;
 122
 123	return 0;
 124}
 125
 126static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
 127{
 128	u8 msg[2] = { reg, val };
 129	struct i2c_msg msgs;
 130
 131	msgs.flags = 0;
 132	msgs.addr = id / 2;
 133	msgs.len = 2;
 134	msgs.buf = msg;
 135	return i2c_transfer(i2c, &msgs, 1);
 136}
 137
 138static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
 139{
 140	struct budget_av *budget_av = (struct budget_av *) ca->data;
 141	int result;
 142
 143	if (slot != 0)
 144		return -EINVAL;
 145
 146	saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
 147	udelay(1);
 148
 149	result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
 150	if (result == -ETIMEDOUT) {
 151		ciintf_slot_shutdown(ca, slot);
 152		printk(KERN_INFO "budget-av: cam ejected 1\n");
 153	}
 154	return result;
 155}
 156
 157static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
 158{
 159	struct budget_av *budget_av = (struct budget_av *) ca->data;
 160	int result;
 161
 162	if (slot != 0)
 163		return -EINVAL;
 164
 165	saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
 166	udelay(1);
 167
 168	result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
 169	if (result == -ETIMEDOUT) {
 170		ciintf_slot_shutdown(ca, slot);
 171		printk(KERN_INFO "budget-av: cam ejected 2\n");
 172	}
 173	return result;
 174}
 175
 176static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
 177{
 178	struct budget_av *budget_av = (struct budget_av *) ca->data;
 179	int result;
 180
 181	if (slot != 0)
 182		return -EINVAL;
 183
 184	saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
 185	udelay(1);
 186
 187	result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
 188	if (result == -ETIMEDOUT) {
 189		ciintf_slot_shutdown(ca, slot);
 190		printk(KERN_INFO "budget-av: cam ejected 3\n");
 191		return -ETIMEDOUT;
 192	}
 193	return result;
 194}
 195
 196static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
 197{
 198	struct budget_av *budget_av = (struct budget_av *) ca->data;
 199	int result;
 200
 201	if (slot != 0)
 202		return -EINVAL;
 203
 204	saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
 205	udelay(1);
 206
 207	result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
 208	if (result == -ETIMEDOUT) {
 209		ciintf_slot_shutdown(ca, slot);
 210		printk(KERN_INFO "budget-av: cam ejected 5\n");
 211	}
 212	return result;
 213}
 214
 215static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
 216{
 217	struct budget_av *budget_av = (struct budget_av *) ca->data;
 218	struct saa7146_dev *saa = budget_av->budget.dev;
 219
 220	if (slot != 0)
 221		return -EINVAL;
 222
 223	dprintk(1, "ciintf_slot_reset\n");
 224	budget_av->slot_status = SLOTSTATUS_RESET;
 225
 226	saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
 227
 228	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
 229	msleep(2);
 230	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
 231	msleep(20); /* 20 ms Vcc settling time */
 232
 233	saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
 234	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
 235	msleep(20);
 236
 237	/* reinitialise the frontend if necessary */
 238	if (budget_av->reinitialise_demod)
 239		dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
 240
 241	return 0;
 242}
 243
 244static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
 245{
 246	struct budget_av *budget_av = (struct budget_av *) ca->data;
 247	struct saa7146_dev *saa = budget_av->budget.dev;
 248
 249	if (slot != 0)
 250		return -EINVAL;
 251
 252	dprintk(1, "ciintf_slot_shutdown\n");
 253
 254	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
 255	budget_av->slot_status = SLOTSTATUS_NONE;
 256
 257	return 0;
 258}
 259
 260static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
 261{
 262	struct budget_av *budget_av = (struct budget_av *) ca->data;
 263	struct saa7146_dev *saa = budget_av->budget.dev;
 264
 265	if (slot != 0)
 266		return -EINVAL;
 267
 268	dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
 269
 270	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
 271
 272	return 0;
 273}
 274
 275static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
 276{
 277	struct budget_av *budget_av = (struct budget_av *) ca->data;
 278	struct saa7146_dev *saa = budget_av->budget.dev;
 279	int result;
 280
 281	if (slot != 0)
 282		return -EINVAL;
 283
 284	/* test the card detect line - needs to be done carefully
 285	 * since it never goes high for some CAMs on this interface (e.g. topuptv) */
 286	if (budget_av->slot_status == SLOTSTATUS_NONE) {
 287		saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
 288		udelay(1);
 289		if (saa7146_read(saa, PSR) & MASK_06) {
 290			if (budget_av->slot_status == SLOTSTATUS_NONE) {
 291				budget_av->slot_status = SLOTSTATUS_PRESENT;
 292				printk(KERN_INFO "budget-av: cam inserted A\n");
 293			}
 294		}
 295		saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
 296	}
 297
 298	/* We also try and read from IO memory to work round the above detection bug. If
 299	 * there is no CAM, we will get a timeout. Only done if there is no cam
 300	 * present, since this test actually breaks some cams :(
 301	 *
 302	 * if the CI interface is not open, we also do the above test since we
 303	 * don't care if the cam has problems - we'll be resetting it on open() anyway */
 304	if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
 305		saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
 306		result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
 307		if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
 308			budget_av->slot_status = SLOTSTATUS_PRESENT;
 309			printk(KERN_INFO "budget-av: cam inserted B\n");
 310		} else if (result < 0) {
 311			if (budget_av->slot_status != SLOTSTATUS_NONE) {
 312				ciintf_slot_shutdown(ca, slot);
 313				printk(KERN_INFO "budget-av: cam ejected 5\n");
 314				return 0;
 315			}
 316		}
 317	}
 318
 319	/* read from attribute memory in reset/ready state to know when the CAM is ready */
 320	if (budget_av->slot_status == SLOTSTATUS_RESET) {
 321		result = ciintf_read_attribute_mem(ca, slot, 0);
 322		if (result == 0x1d) {
 323			budget_av->slot_status = SLOTSTATUS_READY;
 324		}
 325	}
 326
 327	/* work out correct return code */
 328	if (budget_av->slot_status != SLOTSTATUS_NONE) {
 329		if (budget_av->slot_status & SLOTSTATUS_READY) {
 330			return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
 331		}
 332		return DVB_CA_EN50221_POLL_CAM_PRESENT;
 333	}
 334	return 0;
 335}
 336
 337static int ciintf_init(struct budget_av *budget_av)
 338{
 339	struct saa7146_dev *saa = budget_av->budget.dev;
 340	int result;
 341
 342	memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
 343
 344	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
 345	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
 346	saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
 347	saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
 348
 349	/* Enable DEBI pins */
 350	saa7146_write(saa, MC1, MASK_27 | MASK_11);
 351
 352	/* register CI interface */
 353	budget_av->ca.owner = THIS_MODULE;
 354	budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
 355	budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
 356	budget_av->ca.read_cam_control = ciintf_read_cam_control;
 357	budget_av->ca.write_cam_control = ciintf_write_cam_control;
 358	budget_av->ca.slot_reset = ciintf_slot_reset;
 359	budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
 360	budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
 361	budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
 362	budget_av->ca.data = budget_av;
 363	budget_av->budget.ci_present = 1;
 364	budget_av->slot_status = SLOTSTATUS_NONE;
 365
 366	if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
 367					  &budget_av->ca, 0, 1)) != 0) {
 368		printk(KERN_ERR "budget-av: ci initialisation failed.\n");
 369		goto error;
 370	}
 371
 372	printk(KERN_INFO "budget-av: ci interface initialised.\n");
 373	return 0;
 374
 375error:
 376	saa7146_write(saa, MC1, MASK_27);
 377	return result;
 378}
 379
 380static void ciintf_deinit(struct budget_av *budget_av)
 381{
 382	struct saa7146_dev *saa = budget_av->budget.dev;
 383
 384	saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
 385	saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
 386	saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
 387	saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
 388
 389	/* release the CA device */
 390	dvb_ca_en50221_release(&budget_av->ca);
 391
 392	/* disable DEBI pins */
 393	saa7146_write(saa, MC1, MASK_27);
 394}
 395
 396
 397static const u8 saa7113_tab[] = {
 398	0x01, 0x08,
 399	0x02, 0xc0,
 400	0x03, 0x33,
 401	0x04, 0x00,
 402	0x05, 0x00,
 403	0x06, 0xeb,
 404	0x07, 0xe0,
 405	0x08, 0x28,
 406	0x09, 0x00,
 407	0x0a, 0x80,
 408	0x0b, 0x47,
 409	0x0c, 0x40,
 410	0x0d, 0x00,
 411	0x0e, 0x01,
 412	0x0f, 0x44,
 413
 414	0x10, 0x08,
 415	0x11, 0x0c,
 416	0x12, 0x7b,
 417	0x13, 0x00,
 418	0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
 419
 420	0x57, 0xff,
 421	0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
 422	0x5b, 0x83, 0x5e, 0x00,
 423	0xff
 424};
 425
 426static int saa7113_init(struct budget_av *budget_av)
 427{
 428	struct budget *budget = &budget_av->budget;
 429	struct saa7146_dev *saa = budget->dev;
 430	const u8 *data = saa7113_tab;
 431
 432	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
 433	msleep(200);
 434
 435	if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
 436		dprintk(1, "saa7113 not found on KNC card\n");
 437		return -ENODEV;
 438	}
 439
 440	dprintk(1, "saa7113 detected and initializing\n");
 441
 442	while (*data != 0xff) {
 443		i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
 444		data += 2;
 445	}
 446
 447	dprintk(1, "saa7113  status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
 448
 449	return 0;
 450}
 451
 452static int saa7113_setinput(struct budget_av *budget_av, int input)
 453{
 454	struct budget *budget = &budget_av->budget;
 455
 456	if (1 != budget_av->has_saa7113)
 457		return -ENODEV;
 458
 459	if (input == 1) {
 460		i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
 461		i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
 462	} else if (input == 0) {
 463		i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
 464		i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
 465	} else
 466		return -EINVAL;
 467
 468	budget_av->cur_input = input;
 469	return 0;
 470}
 471
 472
 473static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
 474{
 475	u8 aclk = 0;
 476	u8 bclk = 0;
 477	u8 m1;
 478
 479	aclk = 0xb5;
 480	if (srate < 2000000)
 481		bclk = 0x86;
 482	else if (srate < 5000000)
 483		bclk = 0x89;
 484	else if (srate < 15000000)
 485		bclk = 0x8f;
 486	else if (srate < 45000000)
 487		bclk = 0x95;
 488
 489	m1 = 0x14;
 490	if (srate < 4000000)
 491		m1 = 0x10;
 492
 493	stv0299_writereg(fe, 0x13, aclk);
 494	stv0299_writereg(fe, 0x14, bclk);
 495	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
 496	stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
 497	stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
 498	stv0299_writereg(fe, 0x0f, 0x80 | m1);
 499
 500	return 0;
 501}
 502
 503static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe,
 504						 struct dvb_frontend_parameters *params)
 505{
 506	u32 div;
 507	u8 buf[4];
 508	struct budget *budget = (struct budget *) fe->dvb->priv;
 509	struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
 510
 511	if ((params->frequency < 950000) || (params->frequency > 2150000))
 512		return -EINVAL;
 513
 514	div = (params->frequency + (125 - 1)) / 125;	// round correctly
 515	buf[0] = (div >> 8) & 0x7f;
 516	buf[1] = div & 0xff;
 517	buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
 518	buf[3] = 0x20;
 519
 520	if (params->u.qpsk.symbol_rate < 4000000)
 521		buf[3] |= 1;
 522
 523	if (params->frequency < 1250000)
 524		buf[3] |= 0;
 525	else if (params->frequency < 1550000)
 526		buf[3] |= 0x40;
 527	else if (params->frequency < 2050000)
 528		buf[3] |= 0x80;
 529	else if (params->frequency < 2150000)
 530		buf[3] |= 0xC0;
 531
 532	if (fe->ops.i2c_gate_ctrl)
 533		fe->ops.i2c_gate_ctrl(fe, 1);
 534	if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
 535		return -EIO;
 536	return 0;
 537}
 538
 539static u8 typhoon_cinergy1200s_inittab[] = {
 540	0x01, 0x15,
 541	0x02, 0x30,
 542	0x03, 0x00,
 543	0x04, 0x7d,		/* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
 544	0x05, 0x35,		/* I2CT = 0, SCLT = 1, SDAT = 1 */
 545	0x06, 0x40,		/* DAC not used, set to high impendance mode */
 546	0x07, 0x00,		/* DAC LSB */
 547	0x08, 0x40,		/* DiSEqC off */
 548	0x09, 0x00,		/* FIFO */
 549	0x0c, 0x51,		/* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
 550	0x0d, 0x82,		/* DC offset compensation = ON, beta_agc1 = 2 */
 551	0x0e, 0x23,		/* alpha_tmg = 2, beta_tmg = 3 */
 552	0x10, 0x3f,		// AGC2  0x3d
 553	0x11, 0x84,
 554	0x12, 0xb9,
 555	0x15, 0xc9,		// lock detector threshold
 556	0x16, 0x00,
 557	0x17, 0x00,
 558	0x18, 0x00,
 559	0x19, 0x00,
 560	0x1a, 0x00,
 561	0x1f, 0x50,
 562	0x20, 0x00,
 563	0x21, 0x00,
 564	0x22, 0x00,
 565	0x23, 0x00,
 566	0x28, 0x00,		// out imp: normal  out type: parallel FEC mode:0
 567	0x29, 0x1e,		// 1/2 threshold
 568	0x2a, 0x14,		// 2/3 threshold
 569	0x2b, 0x0f,		// 3/4 threshold
 570	0x2c, 0x09,		// 5/6 threshold
 571	0x2d, 0x05,		// 7/8 threshold
 572	0x2e, 0x01,
 573	0x31, 0x1f,		// test all FECs
 574	0x32, 0x19,		// viterbi and synchro search
 575	0x33, 0xfc,		// rs control
 576	0x34, 0x93,		// error control
 577	0x0f, 0x92,
 578	0xff, 0xff
 579};
 580
 581static struct stv0299_config typhoon_config = {
 582	.demod_address = 0x68,
 583	.inittab = typhoon_cinergy1200s_inittab,
 584	.mclk = 88000000UL,
 585	.invert = 0,
 586	.skip_reinit = 0,
 587	.lock_output = STV0299_LOCKOUTPUT_1,
 588	.volt13_op0_op1 = STV0299_VOLT13_OP0,
 589	.min_delay_ms = 100,
 590	.set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
 591};
 592
 593
 594static struct stv0299_config cinergy_1200s_config = {
 595	.demod_address = 0x68,
 596	.inittab = typhoon_cinergy1200s_inittab,
 597	.mclk = 88000000UL,
 598	.invert = 0,
 599	.skip_reinit = 0,
 600	.lock_output = STV0299_LOCKOUTPUT_0,
 601	.volt13_op0_op1 = STV0299_VOLT13_OP0,
 602	.min_delay_ms = 100,
 603	.set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
 604};
 605
 606static struct stv0299_config cinergy_1200s_1894_0010_config = {
 607	.demod_address = 0x68,
 608	.inittab = typhoon_cinergy1200s_inittab,
 609	.mclk = 88000000UL,
 610	.invert = 1,
 611	.skip_reinit = 0,
 612	.lock_output = STV0299_LOCKOUTPUT_1,
 613	.volt13_op0_op1 = STV0299_VOLT13_OP0,
 614	.min_delay_ms = 100,
 615	.set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
 616};
 617
 618static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
 619{
 620	struct budget *budget = (struct budget *) fe->dvb->priv;
 621	u8 buf[6];
 622	struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
 623	int i;
 624
 625#define CU1216_IF 36125000
 626#define TUNER_MUL 62500
 627
 628	u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
 629
 630	buf[0] = (div >> 8) & 0x7f;
 631	buf[1] = div & 0xff;
 632	buf[2] = 0xce;
 633	buf[3] = (params->frequency < 150000000 ? 0x01 :
 634		  params->frequency < 445000000 ? 0x02 : 0x04);
 635	buf[4] = 0xde;
 636	buf[5] = 0x20;
 637
 638	if (fe->ops.i2c_gate_ctrl)
 639		fe->ops.i2c_gate_ctrl(fe, 1);
 640	if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
 641		return -EIO;
 642
 643	/* wait for the pll lock */
 644	msg.flags = I2C_M_RD;
 645	msg.len = 1;
 646	for (i = 0; i < 20; i++) {
 647		if (fe->ops.i2c_gate_ctrl)
 648			fe->ops.i2c_gate_ctrl(fe, 1);
 649		if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
 650			break;
 651		msleep(10);
 652	}
 653
 654	/* switch the charge pump to the lower current */
 655	msg.flags = 0;
 656	msg.len = 2;
 657	msg.buf = &buf[2];
 658	buf[2] &= ~0x40;
 659	if (fe->ops.i2c_gate_ctrl)
 660		fe->ops.i2c_gate_ctrl(fe, 1);
 661	if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
 662		return -EIO;
 663
 664	return 0;
 665}
 666
 667static struct tda1002x_config philips_cu1216_config = {
 668	.demod_address = 0x0c,
 669	.invert = 1,
 670};
 671
 672static struct tda1002x_config philips_cu1216_config_altaddress = {
 673	.demod_address = 0x0d,
 674	.invert = 0,
 675};
 676
 677static struct tda10023_config philips_cu1216_tda10023_config = {
 678	.demod_address = 0x0c,
 679	.invert = 1,
 680};
 681
 682static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
 683{
 684	struct budget *budget = (struct budget *) fe->dvb->priv;
 685	static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
 686	struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
 687
 688	// setup PLL configuration
 689	if (fe->ops.i2c_gate_ctrl)
 690		fe->ops.i2c_gate_ctrl(fe, 1);
 691	if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
 692		return -EIO;
 693	msleep(1);
 694
 695	return 0;
 696}
 697
 698static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
 699{
 700	struct budget *budget = (struct budget *) fe->dvb->priv;
 701	u8 tuner_buf[4];
 702	struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
 703			sizeof(tuner_buf) };
 704	int tuner_frequency = 0;
 705	u8 band, cp, filter;
 706
 707	// determine charge pump
 708	tuner_frequency = params->frequency + 36166000;
 709	if (tuner_frequency < 87000000)
 710		return -EINVAL;
 711	else if (tuner_frequency < 130000000)
 712		cp = 3;
 713	else if (tuner_frequency < 160000000)
 714		cp = 5;
 715	else if (tuner_frequency < 200000000)
 716		cp = 6;
 717	else if (tuner_frequency < 290000000)
 718		cp = 3;
 719	else if (tuner_frequency < 420000000)
 720		cp = 5;
 721	else if (tuner_frequency < 480000000)
 722		cp = 6;
 723	else if (tuner_frequency < 620000000)
 724		cp = 3;
 725	else if (tuner_frequency < 830000000)
 726		cp = 5;
 727	else if (tuner_frequency < 895000000)
 728		cp = 7;
 729	else
 730		return -EINVAL;
 731
 732	// determine band
 733	if (params->frequency < 49000000)
 734		return -EINVAL;
 735	else if (params->frequency < 161000000)
 736		band = 1;
 737	else if (params->frequency < 444000000)
 738		band = 2;
 739	else if (params->frequency < 861000000)
 740		band = 4;
 741	else
 742		return -EINVAL;
 743
 744	// setup PLL filter
 745	switch (params->u.ofdm.bandwidth) {
 746	case BANDWIDTH_6_MHZ:
 747		filter = 0;
 748		break;
 749
 750	case BANDWIDTH_7_MHZ:
 751		filter = 0;
 752		break;
 753
 754	case BANDWIDTH_8_MHZ:
 755		filter = 1;
 756		break;
 757
 758	default:
 759		return -EINVAL;
 760	}
 761
 762	// calculate divisor
 763	// ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
 764	tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
 765
 766	// setup tuner buffer
 767	tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
 768	tuner_buf[1] = tuner_frequency & 0xff;
 769	tuner_buf[2] = 0xca;
 770	tuner_buf[3] = (cp << 5) | (filter << 3) | band;
 771
 772	if (fe->ops.i2c_gate_ctrl)
 773		fe->ops.i2c_gate_ctrl(fe, 1);
 774	if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
 775		return -EIO;
 776
 777	msleep(1);
 778	return 0;
 779}
 780
 781static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
 782					   const struct firmware **fw, char *name)
 783{
 784	struct budget *budget = (struct budget *) fe->dvb->priv;
 785
 786	return request_firmware(fw, name, &budget->dev->pci->dev);
 787}
 788
 789static struct tda1004x_config philips_tu1216_config = {
 790
 791	.demod_address = 0x8,
 792	.invert = 1,
 793	.invert_oclk = 1,
 794	.xtal_freq = TDA10046_XTAL_4M,
 795	.agc_config = TDA10046_AGC_DEFAULT,
 796	.if_freq = TDA10046_FREQ_3617,
 797	.request_firmware = philips_tu1216_request_firmware,
 798};
 799
 800static u8 philips_sd1878_inittab[] = {
 801	0x01, 0x15,
 802	0x02, 0x30,
 803	0x03, 0x00,
 804	0x04, 0x7d,
 805	0x05, 0x35,
 806	0x06, 0x40,
 807	0x07, 0x00,
 808	0x08, 0x43,
 809	0x09, 0x02,
 810	0x0C, 0x51,
 811	0x0D, 0x82,
 812	0x0E, 0x23,
 813	0x10, 0x3f,
 814	0x11, 0x84,
 815	0x12, 0xb9,
 816	0x15, 0xc9,
 817	0x16, 0x19,
 818	0x17, 0x8c,
 819	0x18, 0x59,
 820	0x19, 0xf8,
 821	0x1a, 0xfe,
 822	0x1c, 0x7f,
 823	0x1d, 0x00,
 824	0x1e, 0x00,
 825	0x1f, 0x50,
 826	0x20, 0x00,
 827	0x21, 0x00,
 828	0x22, 0x00,
 829	0x23, 0x00,
 830	0x28, 0x00,
 831	0x29, 0x28,
 832	0x2a, 0x14,
 833	0x2b, 0x0f,
 834	0x2c, 0x09,
 835	0x2d, 0x09,
 836	0x31, 0x1f,
 837	0x32, 0x19,
 838	0x33, 0xfc,
 839	0x34, 0x93,
 840	0xff, 0xff
 841};
 842
 843static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
 844		u32 srate, u32 ratio)
 845{
 846	u8 aclk = 0;
 847	u8 bclk = 0;
 848	u8 m1;
 849
 850	aclk = 0xb5;
 851	if (srate < 2000000)
 852		bclk = 0x86;
 853	else if (srate < 5000000)
 854		bclk = 0x89;
 855	else if (srate < 15000000)
 856		bclk = 0x8f;
 857	else if (srate < 45000000)
 858		bclk = 0x95;
 859
 860	m1 = 0x14;
 861	if (srate < 4000000)
 862		m1 = 0x10;
 863
 864	stv0299_writereg(fe, 0x0e, 0x23);
 865	stv0299_writereg(fe, 0x0f, 0x94);
 866	stv0299_writereg(fe, 0x10, 0x39);
 867	stv0299_writereg(fe, 0x13, aclk);
 868	stv0299_writereg(fe, 0x14, bclk);
 869	stv0299_writereg(fe, 0x15, 0xc9);
 870	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
 871	stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
 872	stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
 873	stv0299_writereg(fe, 0x0f, 0x80 | m1);
 874
 875	return 0;
 876}
 877
 878static struct stv0299_config philips_sd1878_config = {
 879	.demod_address = 0x68,
 880     .inittab = philips_sd1878_inittab,
 881	.mclk = 88000000UL,
 882	.invert = 0,
 883	.skip_reinit = 0,
 884	.lock_output = STV0299_LOCKOUTPUT_1,
 885	.volt13_op0_op1 = STV0299_VOLT13_OP0,
 886	.min_delay_ms = 100,
 887	.set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
 888};
 889
 890/* KNC1 DVB-S (STB0899) Inittab	*/
 891static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
 892
 893	{ STB0899_DEV_ID		, 0x81 },
 894	{ STB0899_DISCNTRL1		, 0x32 },
 895	{ STB0899_DISCNTRL2		, 0x80 },
 896	{ STB0899_DISRX_ST0		, 0x04 },
 897	{ STB0899_DISRX_ST1		, 0x00 },
 898	{ STB0899_DISPARITY		, 0x00 },
 899	{ STB0899_DISFIFO		, 0x00 },
 900	{ STB0899_DISSTATUS		, 0x20 },
 901	{ STB0899_DISF22		, 0x8c },
 902	{ STB0899_DISF22RX		, 0x9a },
 903	{ STB0899_SYSREG		, 0x0b },
 904	{ STB0899_ACRPRESC		, 0x11 },
 905	{ STB0899_ACRDIV1		, 0x0a },
 906	{ STB0899_ACRDIV2		, 0x05 },
 907	{ STB0899_DACR1			, 0x00 },
 908	{ STB0899_DACR2			, 0x00 },
 909	{ STB0899_OUTCFG		, 0x00 },
 910	{ STB0899_MODECFG		, 0x00 },
 911	{ STB0899_IRQSTATUS_3		, 0x30 },
 912	{ STB0899_IRQSTATUS_2		, 0x00 },
 913	{ STB0899_IRQSTATUS_1		, 0x00 },
 914	{ STB0899_IRQSTATUS_0		, 0x00 },
 915	{ STB0899_IRQMSK_3		, 0xf3 },
 916	{ STB0899_IRQMSK_2		, 0xfc },
 917	{ STB0899_IRQMSK_1		, 0xff },
 918	{ STB0899_IRQMSK_0		, 0xff },
 919	{ STB0899_IRQCFG		, 0x00 },
 920	{ STB0899_I2CCFG		, 0x88 },
 921	{ STB0899_I2CRPT		, 0x58 }, /* Repeater=8, Stop=disabled */
 922	{ STB0899_IOPVALUE5		, 0x00 },
 923	{ STB0899_IOPVALUE4		, 0x20 },
 924	{ STB0899_IOPVALUE3		, 0xc9 },
 925	{ STB0899_IOPVALUE2		, 0x90 },
 926	{ STB0899_IOPVALUE1		, 0x40 },
 927	{ STB0899_IOPVALUE0		, 0x00 },
 928	{ STB0899_GPIO00CFG		, 0x82 },
 929	{ STB0899_GPIO01CFG		, 0x82 },
 930	{ STB0899_GPIO02CFG		, 0x82 },
 931	{ STB0899_GPIO03CFG		, 0x82 },
 932	{ STB0899_GPIO04CFG		, 0x82 },
 933	{ STB0899_GPIO05CFG		, 0x82 },
 934	{ STB0899_GPIO06CFG		, 0x82 },
 935	{ STB0899_GPIO07CFG		, 0x82 },
 936	{ STB0899_GPIO08CFG		, 0x82 },
 937	{ STB0899_GPIO09CFG		, 0x82 },
 938	{ STB0899_GPIO10CFG		, 0x82 },
 939	{ STB0899_GPIO11CFG		, 0x82 },
 940	{ STB0899_GPIO12CFG		, 0x82 },
 941	{ STB0899_GPIO13CFG		, 0x82 },
 942	{ STB0899_GPIO14CFG		, 0x82 },
 943	{ STB0899_GPIO15CFG		, 0x82 },
 944	{ STB0899_GPIO16CFG		, 0x82 },
 945	{ STB0899_GPIO17CFG		, 0x82 },
 946	{ STB0899_GPIO18CFG		, 0x82 },
 947	{ STB0899_GPIO19CFG		, 0x82 },
 948	{ STB0899_GPIO20CFG		, 0x82 },
 949	{ STB0899_SDATCFG		, 0xb8 },
 950	{ STB0899_SCLTCFG		, 0xba },
 951	{ STB0899_AGCRFCFG		, 0x08 }, /* 0x1c */
 952	{ STB0899_GPIO22		, 0x82 }, /* AGCBB2CFG */
 953	{ STB0899_GPIO21		, 0x91 }, /* AGCBB1CFG */
 954	{ STB0899_DIRCLKCFG		, 0x82 },
 955	{ STB0899_CLKOUT27CFG		, 0x7e },
 956	{ STB0899_STDBYCFG		, 0x82 },
 957	{ STB0899_CS0CFG		, 0x82 },
 958	{ STB0899_CS1CFG		, 0x82 },
 959	{ STB0899_DISEQCOCFG		, 0x20 },
 960	{ STB0899_GPIO32CFG		, 0x82 },
 961	{ STB0899_GPIO33CFG		, 0x82 },
 962	{ STB0899_GPIO34CFG		, 0x82 },
 963	{ STB0899_GPIO35CFG		, 0x82 },
 964	{ STB0899_GPIO36CFG		, 0x82 },
 965	{ STB0899_GPIO37CFG		, 0x82 },
 966	{ STB0899_GPIO38CFG		, 0x82 },
 967	{ STB0899_GPIO39CFG		, 0x82 },
 968	{ STB0899_NCOARSE		, 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
 969	{ STB0899_SYNTCTRL		, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
 970	{ STB0899_FILTCTRL		, 0x00 },
 971	{ STB0899_SYSCTRL		, 0x00 },
 972	{ STB0899_STOPCLK1		, 0x20 },
 973	{ STB0899_STOPCLK2		, 0x00 },
 974	{ STB0899_INTBUFSTATUS		, 0x00 },
 975	{ STB0899_INTBUFCTRL		, 0x0a },
 976	{ 0xffff			, 0xff },
 977};
 978
 979static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
 980	{ STB0899_DEMOD			, 0x00 },
 981	{ STB0899_RCOMPC		, 0xc9 },
 982	{ STB0899_AGC1CN		, 0x41 },
 983	{ STB0899_AGC1REF		, 0x08 },
 984	{ STB0899_RTC			, 0x7a },
 985	{ STB0899_TMGCFG		, 0x4e },
 986	{ STB0899_AGC2REF		, 0x33 },
 987	{ STB0899_TLSR			, 0x84 },
 988	{ STB0899_CFD			, 0xee },
 989	{ STB0899_ACLC			, 0x87 },
 990	{ STB0899_BCLC			, 0x94 },
 991	{ STB0899_EQON			, 0x41 },
 992	{ STB0899_LDT			, 0xdd },
 993	{ STB0899_LDT2			, 0xc9 },
 994	{ STB0899_EQUALREF		, 0xb4 },
 995	{ STB0899_TMGRAMP		, 0x10 },
 996	{ STB0899_TMGTHD		, 0x30 },
 997	{ STB0899_IDCCOMP		, 0xfb },
 998	{ STB0899_QDCCOMP		, 0x03 },
 999	{ STB0899_POWERI		, 0x3b },
1000	{ STB0899_POWERQ		, 0x3d },
1001	{ STB0899_RCOMP			, 0x81 },
1002	{ STB0899_AGCIQIN		, 0x80 },
1003	{ STB0899_AGC2I1		, 0x04 },
1004	{ STB0899_AGC2I2		, 0xf5 },
1005	{ STB0899_TLIR			, 0x25 },
1006	{ STB0899_RTF			, 0x80 },
1007	{ STB0899_DSTATUS		, 0x00 },
1008	{ STB0899_LDI			, 0xca },
1009	{ STB0899_CFRM			, 0xf1 },
1010	{ STB0899_CFRL			, 0xf3 },
1011	{ STB0899_NIRM			, 0x2a },
1012	{ STB0899_NIRL			, 0x05 },
1013	{ STB0899_ISYMB			, 0x17 },
1014	{ STB0899_QSYMB			, 0xfa },
1015	{ STB0899_SFRH			, 0x2f },
1016	{ STB0899_SFRM			, 0x68 },
1017	{ STB0899_SFRL			, 0x40 },
1018	{ STB0899_SFRUPH		, 0x2f },
1019	{ STB0899_SFRUPM		, 0x68 },
1020	{ STB0899_SFRUPL		, 0x40 },
1021	{ STB0899_EQUAI1		, 0xfd },
1022	{ STB0899_EQUAQ1		, 0x04 },
1023	{ STB0899_EQUAI2		, 0x0f },
1024	{ STB0899_EQUAQ2		, 0xff },
1025	{ STB0899_EQUAI3		, 0xdf },
1026	{ STB0899_EQUAQ3		, 0xfa },
1027	{ STB0899_EQUAI4		, 0x37 },
1028	{ STB0899_EQUAQ4		, 0x0d },
1029	{ STB0899_EQUAI5		, 0xbd },
1030	{ STB0899_EQUAQ5		, 0xf7 },
1031	{ STB0899_DSTATUS2		, 0x00 },
1032	{ STB0899_VSTATUS		, 0x00 },
1033	{ STB0899_VERROR		, 0xff },
1034	{ STB0899_IQSWAP		, 0x2a },
1035	{ STB0899_ECNT1M		, 0x00 },
1036	{ STB0899_ECNT1L		, 0x00 },
1037	{ STB0899_ECNT2M		, 0x00 },
1038	{ STB0899_ECNT2L		, 0x00 },
1039	{ STB0899_ECNT3M		, 0x00 },
1040	{ STB0899_ECNT3L		, 0x00 },
1041	{ STB0899_FECAUTO1		, 0x06 },
1042	{ STB0899_FECM			, 0x01 },
1043	{ STB0899_VTH12			, 0xf0 },
1044	{ STB0899_VTH23			, 0xa0 },
1045	{ STB0899_VTH34			, 0x78 },
1046	{ STB0899_VTH56			, 0x4e },
1047	{ STB0899_VTH67			, 0x48 },
1048	{ STB0899_VTH78			, 0x38 },
1049	{ STB0899_PRVIT			, 0xff },
1050	{ STB0899_VITSYNC		, 0x19 },
1051	{ STB0899_RSULC			, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1052	{ STB0899_TSULC			, 0x42 },
1053	{ STB0899_RSLLC			, 0x40 },
1054	{ STB0899_TSLPL			, 0x12 },
1055	{ STB0899_TSCFGH		, 0x0c },
1056	{ STB0899_TSCFGM		, 0x00 },
1057	{ STB0899_TSCFGL		, 0x0c },
1058	{ STB0899_TSOUT			, 0x4d }, /* 0x0d for CAM */
1059	{ STB0899_RSSYNCDEL		, 0x00 },
1060	{ STB0899_TSINHDELH		, 0x02 },
1061	{ STB0899_TSINHDELM		, 0x00 },
1062	{ STB0899_TSINHDELL		, 0x00 },
1063	{ STB0899_TSLLSTKM		, 0x00 },
1064	{ STB0899_TSLLSTKL		, 0x00 },
1065	{ STB0899_TSULSTKM		, 0x00 },
1066	{ STB0899_TSULSTKL		, 0xab },
1067	{ STB0899_PCKLENUL		, 0x00 },
1068	{ STB0899_PCKLENLL		, 0xcc },
1069	{ STB0899_RSPCKLEN		, 0xcc },
1070	{ STB0899_TSSTATUS		, 0x80 },
1071	{ STB0899_ERRCTRL1		, 0xb6 },
1072	{ STB0899_ERRCTRL2		, 0x96 },
1073	{ STB0899_ERRCTRL3		, 0x89 },
1074	{ STB0899_DMONMSK1		, 0x27 },
1075	{ STB0899_DMONMSK0		, 0x03 },
1076	{ STB0899_DEMAPVIT		, 0x5c },
1077	{ STB0899_PLPARM		, 0x1f },
1078	{ STB0899_PDELCTRL		, 0x48 },
1079	{ STB0899_PDELCTRL2		, 0x00 },
1080	{ STB0899_BBHCTRL1		, 0x00 },
1081	{ STB0899_BBHCTRL2		, 0x00 },
1082	{ STB0899_HYSTTHRESH		, 0x77 },
1083	{ STB0899_MATCSTM		, 0x00 },
1084	{ STB0899_MATCSTL		, 0x00 },
1085	{ STB0899_UPLCSTM		, 0x00 },
1086	{ STB0899_UPLCSTL		, 0x00 },
1087	{ STB0899_DFLCSTM		, 0x00 },
1088	{ STB0899_DFLCSTL		, 0x00 },
1089	{ STB0899_SYNCCST		, 0x00 },
1090	{ STB0899_SYNCDCSTM		, 0x00 },
1091	{ STB0899_SYNCDCSTL		, 0x00 },
1092	{ STB0899_ISI_ENTRY		, 0x00 },
1093	{ STB0899_ISI_BIT_EN		, 0x00 },
1094	{ STB0899_MATSTRM		, 0x00 },
1095	{ STB0899_MATSTRL		, 0x00 },
1096	{ STB0899_UPLSTRM		, 0x00 },
1097	{ STB0899_UPLSTRL		, 0x00 },
1098	{ STB0899_DFLSTRM		, 0x00 },
1099	{ STB0899_DFLSTRL		, 0x00 },
1100	{ STB0899_SYNCSTR		, 0x00 },
1101	{ STB0899_SYNCDSTRM		, 0x00 },
1102	{ STB0899_SYNCDSTRL		, 0x00 },
1103	{ STB0899_CFGPDELSTATUS1	, 0x10 },
1104	{ STB0899_CFGPDELSTATUS2	, 0x00 },
1105	{ STB0899_BBFERRORM		, 0x00 },
1106	{ STB0899_BBFERRORL		, 0x00 },
1107	{ STB0899_UPKTERRORM		, 0x00 },
1108	{ STB0899_UPKTERRORL		, 0x00 },
1109	{ 0xffff			, 0xff },
1110};
1111
1112/* STB0899 demodulator config for the KNC1 and clones */
1113static struct stb0899_config knc1_dvbs2_config = {
1114	.init_dev		= knc1_stb0899_s1_init_1,
1115	.init_s2_demod		= stb0899_s2_init_2,
1116	.init_s1_demod		= knc1_stb0899_s1_init_3,
1117	.init_s2_fec		= stb0899_s2_init_4,
1118	.init_tst		= stb0899_s1_init_5,
1119
1120	.postproc		= NULL,
1121
1122	.demod_address		= 0x68,
1123//	.ts_output_mode		= STB0899_OUT_PARALLEL,	/* types = SERIAL/PARALLEL	*/
1124	.block_sync_mode	= STB0899_SYNC_FORCED,	/* DSS, SYNC_FORCED/UNSYNCED	*/
1125//	.ts_pfbit_toggle	= STB0899_MPEG_NORMAL,	/* DirecTV, MPEG toggling seq	*/
1126
1127	.xtal_freq		= 27000000,
1128	.inversion		= IQ_SWAP_OFF, /* 1 */
1129
1130	.lo_clk			= 76500000,
1131	.hi_clk			= 90000000,
1132
1133	.esno_ave		= STB0899_DVBS2_ESNO_AVE,
1134	.esno_quant		= STB0899_DVBS2_ESNO_QUANT,
1135	.avframes_coarse	= STB0899_DVBS2_AVFRAMES_COARSE,
1136	.avframes_fine		= STB0899_DVBS2_AVFRAMES_FINE,
1137	.miss_threshold		= STB0899_DVBS2_MISS_THRESHOLD,
1138	.uwp_threshold_acq	= STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1139	.uwp_threshold_track	= STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1140	.uwp_threshold_sof	= STB0899_DVBS2_UWP_THRESHOLD_SOF,
1141	.sof_search_timeout	= STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1142
1143	.btr_nco_bits		= STB0899_DVBS2_BTR_NCO_BITS,
1144	.btr_gain_shift_offset	= STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1145	.crl_nco_bits		= STB0899_DVBS2_CRL_NCO_BITS,
1146	.ldpc_max_iter		= STB0899_DVBS2_LDPC_MAX_ITER,
1147
1148	.tuner_get_frequency	= tda8261_get_frequency,
1149	.tuner_set_frequency	= tda8261_set_frequency,
1150	.tuner_set_bandwidth	= NULL,
1151	.tuner_get_bandwidth	= tda8261_get_bandwidth,
1152	.tuner_set_rfsiggain	= NULL
1153};
1154
1155/*
1156 * SD1878/SHA tuner config
1157 * 1F, Single I/P, Horizontal mount, High Sensitivity
1158 */
1159static const struct tda8261_config sd1878c_config = {
1160//	.name		= "SD1878/SHA",
1161	.addr		= 0x60,
1162	.step_size	= TDA8261_STEP_1000 /* kHz */
1163};
1164
1165static u8 read_pwm(struct budget_av *budget_av)
1166{
1167	u8 b = 0xff;
1168	u8 pwm;
1169	struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
1170	{.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
1171	};
1172
1173	if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
1174	    || (pwm == 0xff))
1175		pwm = 0x48;
1176
1177	return pwm;
1178}
1179
1180#define SUBID_DVBS_KNC1			0x0010
1181#define SUBID_DVBS_KNC1_PLUS		0x0011
1182#define SUBID_DVBS_TYPHOON		0x4f56
1183#define SUBID_DVBS_CINERGY1200		0x1154
1184#define SUBID_DVBS_CYNERGY1200N 	0x1155
1185#define SUBID_DVBS_TV_STAR		0x0014
1186#define SUBID_DVBS_TV_STAR_PLUS_X4	0x0015
1187#define SUBID_DVBS_TV_STAR_CI		0x0016
1188#define SUBID_DVBS2_KNC1		0x0018
1189#define SUBID_DVBS2_KNC1_OEM		0x0019
1190#define SUBID_DVBS_EASYWATCH_1  	0x001a
1191#define SUBID_DVBS_EASYWATCH_2  	0x001b
1192#define SUBID_DVBS2_EASYWATCH		0x001d
1193#define SUBID_DVBS_EASYWATCH		0x001e
1194
1195#define SUBID_DVBC_EASYWATCH		0x002a
1196#define SUBID_DVBC_EASYWATCH_MK3	0x002c
1197#define SUBID_DVBC_KNC1			0x0020
1198#define SUBID_DVBC_KNC1_PLUS		0x0021
1199#define SUBID_DVBC_KNC1_MK3		0x0022
1200#define SUBID_DVBC_KNC1_PLUS_MK3	0x0023
1201#define SUBID_DVBC_CINERGY1200		0x1156
1202#define SUBID_DVBC_CINERGY1200_MK3	0x1176
1203
1204#define SUBID_DVBT_EASYWATCH		0x003a
1205#define SUBID_DVBT_KNC1_PLUS		0x0031
1206#define SUBID_DVBT_KNC1			0x0030
1207#define SUBID_DVBT_CINERGY1200		0x1157
1208
1209static void frontend_init(struct budget_av *budget_av)
1210{
1211	struct saa7146_dev * saa = budget_av->budget.dev;
1212	struct dvb_frontend * fe = NULL;
1213
1214	/* Enable / PowerON Frontend */
1215	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
1216
1217	/* Wait for PowerON */
1218	msleep(100);
1219
1220	/* additional setup necessary for the PLUS cards */
1221	switch (saa->pci->subsystem_device) {
1222		case SUBID_DVBS_KNC1_PLUS:
1223		case SUBID_DVBC_KNC1_PLUS:
1224		case SUBID_DVBT_KNC1_PLUS:
1225		case SUBID_DVBC_EASYWATCH:
1226		case SUBID_DVBC_KNC1_PLUS_MK3:
1227		case SUBID_DVBS2_KNC1:
1228		case SUBID_DVBS2_KNC1_OEM:
1229		case SUBID_DVBS2_EASYWATCH:
1230			saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
1231			break;
1232	}
1233
1234	switch (saa->pci->subsystem_device) {
1235
1236	case SUBID_DVBS_KNC1:
1237		/*
1238		 * maybe that setting is needed for other dvb-s cards as well,
1239		 * but so far it has been only confirmed for this type
1240		 */
1241		budget_av->reinitialise_demod = 1;
1242		/* fall through */
1243	case SUBID_DVBS_KNC1_PLUS:
1244	case SUBID_DVBS_EASYWATCH_1:
1245		if (saa->pci->subsystem_vendor == 0x1894) {
1246			fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
1247					     &budget_av->budget.i2c_adap);
1248			if (fe) {
1249				dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
1250			}
1251		} else {
1252			fe = dvb_attach(stv0299_attach, &typhoon_config,
1253					     &budget_av->budget.i2c_adap);
1254			if (fe) {
1255				fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1256			}
1257		}
1258		break;
1259
1260	case SUBID_DVBS_TV_STAR:
1261	case SUBID_DVBS_TV_STAR_PLUS_X4:
1262	case SUBID_DVBS_TV_STAR_CI:
1263	case SUBID_DVBS_CYNERGY1200N:
1264	case SUBID_DVBS_EASYWATCH:
1265	case SUBID_DVBS_EASYWATCH_2:
1266		fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
1267				&budget_av->budget.i2c_adap);
1268		if (fe) {
1269			dvb_attach(dvb_pll_attach, fe, 0x60,
1270				   &budget_av->budget.i2c_adap,
1271				   DVB_PLL_PHILIPS_SD1878_TDA8261);
1272		}
1273		break;
1274
1275	case SUBID_DVBS_TYPHOON:
1276		fe = dvb_attach(stv0299_attach, &typhoon_config,
1277				    &budget_av->budget.i2c_adap);
1278		if (fe) {
1279			fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1280		}
1281		break;
1282	case SUBID_DVBS2_KNC1:
1283	case SUBID_DVBS2_KNC1_OEM:
1284	case SUBID_DVBS2_EASYWATCH:
1285		budget_av->reinitialise_demod = 1;
1286		if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
1287			dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
1288
1289		break;
1290	case SUBID_DVBS_CINERGY1200:
1291		fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
1292				    &budget_av->budget.i2c_adap);
1293		if (fe) {
1294			fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1295		}
1296		break;
1297
1298	case SUBID_DVBC_KNC1:
1299	case SUBID_DVBC_KNC1_PLUS:
1300	case SUBID_DVBC_CINERGY1200:
1301	case SUBID_DVBC_EASYWATCH:
1302		budget_av->reinitialise_demod = 1;
1303		budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1304		fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
1305				     &budget_av->budget.i2c_adap,
1306				     read_pwm(budget_av));
1307		if (fe == NULL)
1308			fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
1309					     &budget_av->budget.i2c_adap,
1310					     read_pwm(budget_av));
1311		if (fe) {
1312			fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1313		}
1314		break;
1315
1316	case SUBID_DVBC_EASYWATCH_MK3:
1317	case SUBID_DVBC_CINERGY1200_MK3:
1318	case SUBID_DVBC_KNC1_MK3:
1319	case SUBID_DVBC_KNC1_PLUS_MK3:
1320		budget_av->reinitialise_demod = 1;
1321		budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1322		fe = dvb_attach(tda10023_attach,
1323			&philips_cu1216_tda10023_config,
1324			&budget_av->budget.i2c_adap,
1325			read_pwm(budget_av));
1326		if (fe) {
1327			fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1328		}
1329		break;
1330
1331	case SUBID_DVBT_EASYWATCH:
1332	case SUBID_DVBT_KNC1:
1333	case SUBID_DVBT_KNC1_PLUS:
1334	case SUBID_DVBT_CINERGY1200:
1335		budget_av->reinitialise_demod = 1;
1336		fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
1337				     &budget_av->budget.i2c_adap);
1338		if (fe) {
1339			fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1340			fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
1341		}
1342		break;
1343	}
1344
1345	if (fe == NULL) {
1346		printk(KERN_ERR "budget-av: A frontend driver was not found "
1347				"for device [%04x:%04x] subsystem [%04x:%04x]\n",
1348		       saa->pci->vendor,
1349		       saa->pci->device,
1350		       saa->pci->subsystem_vendor,
1351		       saa->pci->subsystem_device);
1352		return;
1353	}
1354
1355	budget_av->budget.dvb_frontend = fe;
1356
1357	if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1358				  budget_av->budget.dvb_frontend)) {
1359		printk(KERN_ERR "budget-av: Frontend registration failed!\n");
1360		dvb_frontend_detach(budget_av->budget.dvb_frontend);
1361		budget_av->budget.dvb_frontend = NULL;
1362	}
1363}
1364
1365
1366static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1367{
1368	struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1369
1370	dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1371
1372	if (*isr & MASK_10)
1373		ttpci_budget_irq10_handler(dev, isr);
1374}
1375
1376static int budget_av_detach(struct saa7146_dev *dev)
1377{
1378	struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1379	int err;
1380
1381	dprintk(2, "dev: %p\n", dev);
1382
1383	if (1 == budget_av->has_saa7113) {
1384		saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
1385
1386		msleep(200);
1387
1388		saa7146_unregister_device(&budget_av->vd, dev);
1389
1390		saa7146_vv_release(dev);
1391	}
1392
1393	if (budget_av->budget.ci_present)
1394		ciintf_deinit(budget_av);
1395
1396	if (budget_av->budget.dvb_frontend != NULL) {
1397		dvb_unregister_frontend(budget_av->budget.dvb_frontend);
1398		dvb_frontend_detach(budget_av->budget.dvb_frontend);
1399	}
1400	err = ttpci_budget_deinit(&budget_av->budget);
1401
1402	kfree(budget_av);
1403
1404	return err;
1405}
1406
1407#define KNC1_INPUTS 2
1408static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1409	{ 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0,
1410		V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
1411	{ 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0,
1412		V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
1413};
1414
1415static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
1416{
1417	dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
1418	if (i->index >= KNC1_INPUTS)
1419		return -EINVAL;
1420	memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1421	return 0;
1422}
1423
1424static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1425{
1426	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1427	struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1428
1429	*i = budget_av->cur_input;
1430
1431	dprintk(1, "VIDIOC_G_INPUT %d.\n", *i);
1432	return 0;
1433}
1434
1435static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
1436{
1437	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1438	struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1439
1440	dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
1441	return saa7113_setinput(budget_av, input);
1442}
1443
1444static struct saa7146_ext_vv vv_data;
1445
1446static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1447{
1448	struct budget_av *budget_av;
1449	u8 *mac;
1450	int err;
1451
1452	dprintk(2, "dev: %p\n", dev);
1453
1454	if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
1455		return -ENOMEM;
1456
1457	budget_av->has_saa7113 = 0;
1458	budget_av->budget.ci_present = 0;
1459
1460	dev->ext_priv = budget_av;
1461
1462	err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
1463				adapter_nr);
1464	if (err) {
1465		kfree(budget_av);
1466		return err;
1467	}
1468
1469	/* knc1 initialization */
1470	saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1471	saa7146_write(dev, DD1_INIT, 0x07000600);
1472	saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
1473
1474	if (saa7113_init(budget_av) == 0) {
1475		budget_av->has_saa7113 = 1;
1476
1477		if (0 != saa7146_vv_init(dev, &vv_data)) {
1478			/* fixme: proper cleanup here */
1479			ERR(("cannot init vv subsystem.\n"));
1480			return err;
1481		}
1482		vv_data.ops.vidioc_enum_input = vidioc_enum_input;
1483		vv_data.ops.vidioc_g_input = vidioc_g_input;
1484		vv_data.ops.vidioc_s_input = vidioc_s_input;
1485
1486		if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1487			/* fixme: proper cleanup here */
1488			ERR(("cannot register capture v4l2 device.\n"));
1489			saa7146_vv_release(dev);
1490			return err;
1491		}
1492
1493		/* beware: this modifies dev->vv ... */
1494		saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
1495						SAA7146_HPS_SYNC_PORT_A);
1496
1497		saa7113_setinput(budget_av, 0);
1498	}
1499
1500	/* fixme: find some sane values here... */
1501	saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1502
1503	mac = budget_av->budget.dvb_adapter.proposed_mac;
1504	if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
1505		printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n",
1506		       budget_av->budget.dvb_adapter.num);
1507		memset(mac, 0, 6);
1508	} else {
1509		printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
1510		       budget_av->budget.dvb_adapter.num,
1511		       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1512	}
1513
1514	budget_av->budget.dvb_adapter.priv = budget_av;
1515	frontend_init(budget_av);
1516	ciintf_init(budget_av);
1517
1518	ttpci_budget_init_hooks(&budget_av->budget);
1519
1520	return 0;
1521}
1522
1523static struct saa7146_standard standard[] = {
1524	{.name = "PAL",.id = V4L2_STD_PAL,
1525	 .v_offset = 0x17,.v_field = 288,
1526	 .h_offset = 0x14,.h_pixels = 680,
1527	 .v_max_out = 576,.h_max_out = 768 },
1528
1529	{.name = "NTSC",.id = V4L2_STD_NTSC,
1530	 .v_offset = 0x16,.v_field = 240,
1531	 .h_offset = 0x06,.h_pixels = 708,
1532	 .v_max_out = 480,.h_max_out = 640, },
1533};
1534
1535static struct saa7146_ext_vv vv_data = {
1536	.inputs = 2,
1537	.capabilities = 0,	// perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
1538	.flags = 0,
1539	.stds = &standard[0],
1540	.num_stds = ARRAY_SIZE(standard),
1541};
1542
1543static struct saa7146_extension budget_extension;
1544
1545MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
1546MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
1547MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
1548MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1549MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
1550MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
1551MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
1552MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
1553MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
1554MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
1555MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
1556MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
1557MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
1558MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
1559MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
1560MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
1561MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
1562MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
1563MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1564MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1565MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
1566MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
1567MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1568
1569static struct pci_device_id pci_tbl[] = {
1570	MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
1571	MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
1572	MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
1573	MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
1574	MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
1575	MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
1576	MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
1577	MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
1578	MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
1579	MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
1580	MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
1581	MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1582	MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1583	MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
1584	MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
1585	MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
1586	MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
1587	MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1588	MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
1589	MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
1590	MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
1591	MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
1592	MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
1593	MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
1594	MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
1595	MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
1596	MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
1597	MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1598	{
1599	 .vendor = 0,
1600	}
1601};
1602
1603MODULE_DEVICE_TABLE(pci, pci_tbl);
1604
1605static struct saa7146_extension budget_extension = {
1606	.name = "budget_av",
1607	.flags = SAA7146_USE_I2C_IRQ,
1608
1609	.pci_tbl = pci_tbl,
1610
1611	.module = THIS_MODULE,
1612	.attach = budget_av_attach,
1613	.detach = budget_av_detach,
1614
1615	.irq_mask = MASK_10,
1616	.irq_func = budget_av_irq,
1617};
1618
1619static int __init budget_av_init(void)
1620{
1621	return saa7146_register_extension(&budget_extension);
1622}
1623
1624static void __exit budget_av_exit(void)
1625{
1626	saa7146_unregister_extension(&budget_extension);
1627}
1628
1629module_init(budget_av_init);
1630module_exit(budget_av_exit);
1631
1632MODULE_LICENSE("GPL");
1633MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1634MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1635		   "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");