cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

budget-av.c (44977B)


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