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-ci.c (44737B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * budget-ci.c: driver for the SAA7146 based Budget DVB cards
      4 *
      5 * Compiled from various sources by Michael Hunold <michael@mihu.de>
      6 *
      7 *     msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
      8 *     partially based on the Siemens DVB driver by Ralph+Marcus Metzler
      9 *
     10 * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
     11 *
     12 * the project's page is at https://linuxtv.org
     13 */
     14
     15#include <linux/module.h>
     16#include <linux/errno.h>
     17#include <linux/slab.h>
     18#include <linux/interrupt.h>
     19#include <linux/spinlock.h>
     20#include <media/rc-core.h>
     21
     22#include "budget.h"
     23
     24#include <media/dvb_ca_en50221.h>
     25#include "stv0299.h"
     26#include "stv0297.h"
     27#include "tda1004x.h"
     28#include "stb0899_drv.h"
     29#include "stb0899_reg.h"
     30#include "stb0899_cfg.h"
     31#include "stb6100.h"
     32#include "stb6100_cfg.h"
     33#include "lnbp21.h"
     34#include "bsbe1.h"
     35#include "bsru6.h"
     36#include "tda1002x.h"
     37#include "tda827x.h"
     38#include "bsbe1-d01a.h"
     39
     40#define MODULE_NAME "budget_ci"
     41
     42/*
     43 * Regarding DEBIADDR_IR:
     44 * Some CI modules hang if random addresses are read.
     45 * Using address 0x4000 for the IR read means that we
     46 * use the same address as for CI version, which should
     47 * be a safe default.
     48 */
     49#define DEBIADDR_IR		0x4000
     50#define DEBIADDR_CICONTROL	0x0000
     51#define DEBIADDR_CIVERSION	0x4000
     52#define DEBIADDR_IO		0x1000
     53#define DEBIADDR_ATTR		0x3000
     54
     55#define CICONTROL_RESET		0x01
     56#define CICONTROL_ENABLETS	0x02
     57#define CICONTROL_CAMDETECT	0x08
     58
     59#define DEBICICTL		0x00420000
     60#define DEBICICAM		0x02420000
     61
     62#define SLOTSTATUS_NONE		1
     63#define SLOTSTATUS_PRESENT	2
     64#define SLOTSTATUS_RESET	4
     65#define SLOTSTATUS_READY	8
     66#define SLOTSTATUS_OCCUPIED	(SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
     67
     68/* RC5 device wildcard */
     69#define IR_DEVICE_ANY		255
     70
     71static int rc5_device = -1;
     72module_param(rc5_device, int, 0644);
     73MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
     74
     75static int ir_debug;
     76module_param(ir_debug, int, 0644);
     77MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
     78
     79DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
     80
     81struct budget_ci_ir {
     82	struct rc_dev *dev;
     83	struct tasklet_struct msp430_irq_tasklet;
     84	char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
     85	char phys[32];
     86	int rc5_device;
     87	u32 ir_key;
     88	bool have_command;
     89	bool full_rc5;		/* Outputs a full RC5 code */
     90};
     91
     92struct budget_ci {
     93	struct budget budget;
     94	struct tasklet_struct ciintf_irq_tasklet;
     95	int slot_status;
     96	int ci_irq;
     97	struct dvb_ca_en50221 ca;
     98	struct budget_ci_ir ir;
     99	u8 tuner_pll_address; /* used for philips_tdm1316l configs */
    100};
    101
    102static void msp430_ir_interrupt(struct tasklet_struct *t)
    103{
    104	struct budget_ci_ir *ir = from_tasklet(ir, t, msp430_irq_tasklet);
    105	struct budget_ci *budget_ci = container_of(ir, typeof(*budget_ci), ir);
    106	struct rc_dev *dev = budget_ci->ir.dev;
    107	u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
    108
    109	/*
    110	 * The msp430 chip can generate two different bytes, command and device
    111	 *
    112	 * type1: X1CCCCCC, C = command bits (0 - 63)
    113	 * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
    114	 *
    115	 * Each signal from the remote control can generate one or more command
    116	 * bytes and one or more device bytes. For the repeated bytes, the
    117	 * highest bit (X) is set. The first command byte is always generated
    118	 * before the first device byte. Other than that, no specific order
    119	 * seems to apply. To make life interesting, bytes can also be lost.
    120	 *
    121	 * Only when we have a command and device byte, a keypress is
    122	 * generated.
    123	 */
    124
    125	if (ir_debug)
    126		printk("budget_ci: received byte 0x%02x\n", command);
    127
    128	/* Remove repeat bit, we use every command */
    129	command = command & 0x7f;
    130
    131	/* Is this a RC5 command byte? */
    132	if (command & 0x40) {
    133		budget_ci->ir.have_command = true;
    134		budget_ci->ir.ir_key = command & 0x3f;
    135		return;
    136	}
    137
    138	/* It's a RC5 device byte */
    139	if (!budget_ci->ir.have_command)
    140		return;
    141	budget_ci->ir.have_command = false;
    142
    143	if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
    144	    budget_ci->ir.rc5_device != (command & 0x1f))
    145		return;
    146
    147	if (budget_ci->ir.full_rc5) {
    148		rc_keydown(dev, RC_PROTO_RC5,
    149			   RC_SCANCODE_RC5(budget_ci->ir.rc5_device, budget_ci->ir.ir_key),
    150			   !!(command & 0x20));
    151		return;
    152	}
    153
    154	/* FIXME: We should generate complete scancodes for all devices */
    155	rc_keydown(dev, RC_PROTO_UNKNOWN, budget_ci->ir.ir_key,
    156		   !!(command & 0x20));
    157}
    158
    159static int msp430_ir_init(struct budget_ci *budget_ci)
    160{
    161	struct saa7146_dev *saa = budget_ci->budget.dev;
    162	struct rc_dev *dev;
    163	int error;
    164
    165	dev = rc_allocate_device(RC_DRIVER_SCANCODE);
    166	if (!dev) {
    167		printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
    168		return -ENOMEM;
    169	}
    170
    171	snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
    172		 "Budget-CI dvb ir receiver %s", saa->name);
    173	snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
    174		 "pci-%s/ir0", pci_name(saa->pci));
    175
    176	dev->driver_name = MODULE_NAME;
    177	dev->device_name = budget_ci->ir.name;
    178	dev->input_phys = budget_ci->ir.phys;
    179	dev->input_id.bustype = BUS_PCI;
    180	dev->input_id.version = 1;
    181	if (saa->pci->subsystem_vendor) {
    182		dev->input_id.vendor = saa->pci->subsystem_vendor;
    183		dev->input_id.product = saa->pci->subsystem_device;
    184	} else {
    185		dev->input_id.vendor = saa->pci->vendor;
    186		dev->input_id.product = saa->pci->device;
    187	}
    188	dev->dev.parent = &saa->pci->dev;
    189
    190	if (rc5_device < 0)
    191		budget_ci->ir.rc5_device = IR_DEVICE_ANY;
    192	else
    193		budget_ci->ir.rc5_device = rc5_device;
    194
    195	/* Select keymap and address */
    196	switch (budget_ci->budget.dev->pci->subsystem_device) {
    197	case 0x100c:
    198	case 0x100f:
    199	case 0x1011:
    200	case 0x1012:
    201		/* The hauppauge keymap is a superset of these remotes */
    202		dev->map_name = RC_MAP_HAUPPAUGE;
    203		budget_ci->ir.full_rc5 = true;
    204
    205		if (rc5_device < 0)
    206			budget_ci->ir.rc5_device = 0x1f;
    207		break;
    208	case 0x1010:
    209	case 0x1017:
    210	case 0x1019:
    211	case 0x101a:
    212	case 0x101b:
    213		/* for the Technotrend 1500 bundled remote */
    214		dev->map_name = RC_MAP_TT_1500;
    215		break;
    216	default:
    217		/* unknown remote */
    218		dev->map_name = RC_MAP_BUDGET_CI_OLD;
    219		break;
    220	}
    221	if (!budget_ci->ir.full_rc5)
    222		dev->scancode_mask = 0xff;
    223
    224	error = rc_register_device(dev);
    225	if (error) {
    226		printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
    227		rc_free_device(dev);
    228		return error;
    229	}
    230
    231	budget_ci->ir.dev = dev;
    232
    233	tasklet_setup(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt);
    234
    235	SAA7146_IER_ENABLE(saa, MASK_06);
    236	saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
    237
    238	return 0;
    239}
    240
    241static void msp430_ir_deinit(struct budget_ci *budget_ci)
    242{
    243	struct saa7146_dev *saa = budget_ci->budget.dev;
    244
    245	SAA7146_IER_DISABLE(saa, MASK_06);
    246	saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
    247	tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
    248
    249	rc_unregister_device(budget_ci->ir.dev);
    250}
    251
    252static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
    253{
    254	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
    255
    256	if (slot != 0)
    257		return -EINVAL;
    258
    259	return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
    260				     DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
    261}
    262
    263static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
    264{
    265	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
    266
    267	if (slot != 0)
    268		return -EINVAL;
    269
    270	return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
    271				      DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
    272}
    273
    274static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
    275{
    276	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
    277
    278	if (slot != 0)
    279		return -EINVAL;
    280
    281	return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
    282				     DEBIADDR_IO | (address & 3), 1, 1, 0);
    283}
    284
    285static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
    286{
    287	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
    288
    289	if (slot != 0)
    290		return -EINVAL;
    291
    292	return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
    293				      DEBIADDR_IO | (address & 3), 1, value, 1, 0);
    294}
    295
    296static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
    297{
    298	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
    299	struct saa7146_dev *saa = budget_ci->budget.dev;
    300
    301	if (slot != 0)
    302		return -EINVAL;
    303
    304	if (budget_ci->ci_irq) {
    305		// trigger on RISING edge during reset so we know when READY is re-asserted
    306		saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
    307	}
    308	budget_ci->slot_status = SLOTSTATUS_RESET;
    309	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
    310	msleep(1);
    311	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
    312			       CICONTROL_RESET, 1, 0);
    313
    314	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
    315	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
    316	return 0;
    317}
    318
    319static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
    320{
    321	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
    322	struct saa7146_dev *saa = budget_ci->budget.dev;
    323
    324	if (slot != 0)
    325		return -EINVAL;
    326
    327	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
    328	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
    329	return 0;
    330}
    331
    332static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
    333{
    334	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
    335	struct saa7146_dev *saa = budget_ci->budget.dev;
    336	int tmp;
    337
    338	if (slot != 0)
    339		return -EINVAL;
    340
    341	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
    342
    343	tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
    344	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
    345			       tmp | CICONTROL_ENABLETS, 1, 0);
    346
    347	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
    348	return 0;
    349}
    350
    351static void ciintf_interrupt(struct tasklet_struct *t)
    352{
    353	struct budget_ci *budget_ci = from_tasklet(budget_ci, t,
    354						   ciintf_irq_tasklet);
    355	struct saa7146_dev *saa = budget_ci->budget.dev;
    356	unsigned int flags;
    357
    358	// ensure we don't get spurious IRQs during initialisation
    359	if (!budget_ci->budget.ci_present)
    360		return;
    361
    362	// read the CAM status
    363	flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
    364	if (flags & CICONTROL_CAMDETECT) {
    365
    366		// GPIO should be set to trigger on falling edge if a CAM is present
    367		saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
    368
    369		if (budget_ci->slot_status & SLOTSTATUS_NONE) {
    370			// CAM insertion IRQ
    371			budget_ci->slot_status = SLOTSTATUS_PRESENT;
    372			dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
    373						     DVB_CA_EN50221_CAMCHANGE_INSERTED);
    374
    375		} else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
    376			// CAM ready (reset completed)
    377			budget_ci->slot_status = SLOTSTATUS_READY;
    378			dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
    379
    380		} else if (budget_ci->slot_status & SLOTSTATUS_READY) {
    381			// FR/DA IRQ
    382			dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
    383		}
    384	} else {
    385
    386		// trigger on rising edge if a CAM is not present - when a CAM is inserted, we
    387		// only want to get the IRQ when it sets READY. If we trigger on the falling edge,
    388		// the CAM might not actually be ready yet.
    389		saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
    390
    391		// generate a CAM removal IRQ if we haven't already
    392		if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
    393			// CAM removal IRQ
    394			budget_ci->slot_status = SLOTSTATUS_NONE;
    395			dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
    396						     DVB_CA_EN50221_CAMCHANGE_REMOVED);
    397		}
    398	}
    399}
    400
    401static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
    402{
    403	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
    404	unsigned int flags;
    405
    406	// ensure we don't get spurious IRQs during initialisation
    407	if (!budget_ci->budget.ci_present)
    408		return -EINVAL;
    409
    410	// read the CAM status
    411	flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
    412	if (flags & CICONTROL_CAMDETECT) {
    413		// mark it as present if it wasn't before
    414		if (budget_ci->slot_status & SLOTSTATUS_NONE) {
    415			budget_ci->slot_status = SLOTSTATUS_PRESENT;
    416		}
    417
    418		// during a RESET, we check if we can read from IO memory to see when CAM is ready
    419		if (budget_ci->slot_status & SLOTSTATUS_RESET) {
    420			if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
    421				budget_ci->slot_status = SLOTSTATUS_READY;
    422			}
    423		}
    424	} else {
    425		budget_ci->slot_status = SLOTSTATUS_NONE;
    426	}
    427
    428	if (budget_ci->slot_status != SLOTSTATUS_NONE) {
    429		if (budget_ci->slot_status & SLOTSTATUS_READY) {
    430			return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
    431		}
    432		return DVB_CA_EN50221_POLL_CAM_PRESENT;
    433	}
    434
    435	return 0;
    436}
    437
    438static int ciintf_init(struct budget_ci *budget_ci)
    439{
    440	struct saa7146_dev *saa = budget_ci->budget.dev;
    441	int flags;
    442	int result;
    443	int ci_version;
    444	int ca_flags;
    445
    446	memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
    447
    448	// enable DEBI pins
    449	saa7146_write(saa, MC1, MASK_27 | MASK_11);
    450
    451	// test if it is there
    452	ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
    453	if ((ci_version & 0xa0) != 0xa0) {
    454		result = -ENODEV;
    455		goto error;
    456	}
    457
    458	// determine whether a CAM is present or not
    459	flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
    460	budget_ci->slot_status = SLOTSTATUS_NONE;
    461	if (flags & CICONTROL_CAMDETECT)
    462		budget_ci->slot_status = SLOTSTATUS_PRESENT;
    463
    464	// version 0xa2 of the CI firmware doesn't generate interrupts
    465	if (ci_version == 0xa2) {
    466		ca_flags = 0;
    467		budget_ci->ci_irq = 0;
    468	} else {
    469		ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
    470				DVB_CA_EN50221_FLAG_IRQ_FR |
    471				DVB_CA_EN50221_FLAG_IRQ_DA;
    472		budget_ci->ci_irq = 1;
    473	}
    474
    475	// register CI interface
    476	budget_ci->ca.owner = THIS_MODULE;
    477	budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
    478	budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
    479	budget_ci->ca.read_cam_control = ciintf_read_cam_control;
    480	budget_ci->ca.write_cam_control = ciintf_write_cam_control;
    481	budget_ci->ca.slot_reset = ciintf_slot_reset;
    482	budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
    483	budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
    484	budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
    485	budget_ci->ca.data = budget_ci;
    486	if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
    487					  &budget_ci->ca,
    488					  ca_flags, 1)) != 0) {
    489		printk("budget_ci: CI interface detected, but initialisation failed.\n");
    490		goto error;
    491	}
    492
    493	// Setup CI slot IRQ
    494	if (budget_ci->ci_irq) {
    495		tasklet_setup(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt);
    496		if (budget_ci->slot_status != SLOTSTATUS_NONE) {
    497			saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
    498		} else {
    499			saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
    500		}
    501		SAA7146_IER_ENABLE(saa, MASK_03);
    502	}
    503
    504	// enable interface
    505	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
    506			       CICONTROL_RESET, 1, 0);
    507
    508	// success!
    509	printk("budget_ci: CI interface initialised\n");
    510	budget_ci->budget.ci_present = 1;
    511
    512	// forge a fake CI IRQ so the CAM state is setup correctly
    513	if (budget_ci->ci_irq) {
    514		flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
    515		if (budget_ci->slot_status != SLOTSTATUS_NONE)
    516			flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
    517		dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
    518	}
    519
    520	return 0;
    521
    522error:
    523	saa7146_write(saa, MC1, MASK_27);
    524	return result;
    525}
    526
    527static void ciintf_deinit(struct budget_ci *budget_ci)
    528{
    529	struct saa7146_dev *saa = budget_ci->budget.dev;
    530
    531	// disable CI interrupts
    532	if (budget_ci->ci_irq) {
    533		SAA7146_IER_DISABLE(saa, MASK_03);
    534		saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
    535		tasklet_kill(&budget_ci->ciintf_irq_tasklet);
    536	}
    537
    538	// reset interface
    539	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
    540	msleep(1);
    541	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
    542			       CICONTROL_RESET, 1, 0);
    543
    544	// disable TS data stream to CI interface
    545	saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
    546
    547	// release the CA device
    548	dvb_ca_en50221_release(&budget_ci->ca);
    549
    550	// disable DEBI pins
    551	saa7146_write(saa, MC1, MASK_27);
    552}
    553
    554static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
    555{
    556	struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
    557
    558	dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
    559
    560	if (*isr & MASK_06)
    561		tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
    562
    563	if (*isr & MASK_10)
    564		ttpci_budget_irq10_handler(dev, isr);
    565
    566	if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
    567		tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
    568}
    569
    570static u8 philips_su1278_tt_inittab[] = {
    571	0x01, 0x0f,
    572	0x02, 0x30,
    573	0x03, 0x00,
    574	0x04, 0x5b,
    575	0x05, 0x85,
    576	0x06, 0x02,
    577	0x07, 0x00,
    578	0x08, 0x02,
    579	0x09, 0x00,
    580	0x0C, 0x01,
    581	0x0D, 0x81,
    582	0x0E, 0x44,
    583	0x0f, 0x14,
    584	0x10, 0x3c,
    585	0x11, 0x84,
    586	0x12, 0xda,
    587	0x13, 0x97,
    588	0x14, 0x95,
    589	0x15, 0xc9,
    590	0x16, 0x19,
    591	0x17, 0x8c,
    592	0x18, 0x59,
    593	0x19, 0xf8,
    594	0x1a, 0xfe,
    595	0x1c, 0x7f,
    596	0x1d, 0x00,
    597	0x1e, 0x00,
    598	0x1f, 0x50,
    599	0x20, 0x00,
    600	0x21, 0x00,
    601	0x22, 0x00,
    602	0x23, 0x00,
    603	0x28, 0x00,
    604	0x29, 0x28,
    605	0x2a, 0x14,
    606	0x2b, 0x0f,
    607	0x2c, 0x09,
    608	0x2d, 0x09,
    609	0x31, 0x1f,
    610	0x32, 0x19,
    611	0x33, 0xfc,
    612	0x34, 0x93,
    613	0xff, 0xff
    614};
    615
    616static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
    617{
    618	stv0299_writereg(fe, 0x0e, 0x44);
    619	if (srate >= 10000000) {
    620		stv0299_writereg(fe, 0x13, 0x97);
    621		stv0299_writereg(fe, 0x14, 0x95);
    622		stv0299_writereg(fe, 0x15, 0xc9);
    623		stv0299_writereg(fe, 0x17, 0x8c);
    624		stv0299_writereg(fe, 0x1a, 0xfe);
    625		stv0299_writereg(fe, 0x1c, 0x7f);
    626		stv0299_writereg(fe, 0x2d, 0x09);
    627	} else {
    628		stv0299_writereg(fe, 0x13, 0x99);
    629		stv0299_writereg(fe, 0x14, 0x8d);
    630		stv0299_writereg(fe, 0x15, 0xce);
    631		stv0299_writereg(fe, 0x17, 0x43);
    632		stv0299_writereg(fe, 0x1a, 0x1d);
    633		stv0299_writereg(fe, 0x1c, 0x12);
    634		stv0299_writereg(fe, 0x2d, 0x05);
    635	}
    636	stv0299_writereg(fe, 0x0e, 0x23);
    637	stv0299_writereg(fe, 0x0f, 0x94);
    638	stv0299_writereg(fe, 0x10, 0x39);
    639	stv0299_writereg(fe, 0x15, 0xc9);
    640
    641	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
    642	stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
    643	stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
    644
    645	return 0;
    646}
    647
    648static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe)
    649{
    650	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
    651	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
    652	u32 div;
    653	u8 buf[4];
    654	struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
    655
    656	if ((p->frequency < 950000) || (p->frequency > 2150000))
    657		return -EINVAL;
    658
    659	div = (p->frequency + (500 - 1)) / 500;	/* round correctly */
    660	buf[0] = (div >> 8) & 0x7f;
    661	buf[1] = div & 0xff;
    662	buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
    663	buf[3] = 0x20;
    664
    665	if (p->symbol_rate < 4000000)
    666		buf[3] |= 1;
    667
    668	if (p->frequency < 1250000)
    669		buf[3] |= 0;
    670	else if (p->frequency < 1550000)
    671		buf[3] |= 0x40;
    672	else if (p->frequency < 2050000)
    673		buf[3] |= 0x80;
    674	else if (p->frequency < 2150000)
    675		buf[3] |= 0xC0;
    676
    677	if (fe->ops.i2c_gate_ctrl)
    678		fe->ops.i2c_gate_ctrl(fe, 1);
    679	if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
    680		return -EIO;
    681	return 0;
    682}
    683
    684static const struct stv0299_config philips_su1278_tt_config = {
    685
    686	.demod_address = 0x68,
    687	.inittab = philips_su1278_tt_inittab,
    688	.mclk = 64000000UL,
    689	.invert = 0,
    690	.skip_reinit = 1,
    691	.lock_output = STV0299_LOCKOUTPUT_1,
    692	.volt13_op0_op1 = STV0299_VOLT13_OP1,
    693	.min_delay_ms = 50,
    694	.set_symbol_rate = philips_su1278_tt_set_symbol_rate,
    695};
    696
    697
    698
    699static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
    700{
    701	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
    702	static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
    703	static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
    704	struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
    705			sizeof(td1316_init) };
    706
    707	// setup PLL configuration
    708	if (fe->ops.i2c_gate_ctrl)
    709		fe->ops.i2c_gate_ctrl(fe, 1);
    710	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
    711		return -EIO;
    712	msleep(1);
    713
    714	// disable the mc44BC374c (do not check for errors)
    715	tuner_msg.addr = 0x65;
    716	tuner_msg.buf = disable_mc44BC374c;
    717	tuner_msg.len = sizeof(disable_mc44BC374c);
    718	if (fe->ops.i2c_gate_ctrl)
    719		fe->ops.i2c_gate_ctrl(fe, 1);
    720	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
    721		if (fe->ops.i2c_gate_ctrl)
    722			fe->ops.i2c_gate_ctrl(fe, 1);
    723		i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
    724	}
    725
    726	return 0;
    727}
    728
    729static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
    730{
    731	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
    732	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
    733	u8 tuner_buf[4];
    734	struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
    735	int tuner_frequency = 0;
    736	u8 band, cp, filter;
    737
    738	// determine charge pump
    739	tuner_frequency = p->frequency + 36130000;
    740	if (tuner_frequency < 87000000)
    741		return -EINVAL;
    742	else if (tuner_frequency < 130000000)
    743		cp = 3;
    744	else if (tuner_frequency < 160000000)
    745		cp = 5;
    746	else if (tuner_frequency < 200000000)
    747		cp = 6;
    748	else if (tuner_frequency < 290000000)
    749		cp = 3;
    750	else if (tuner_frequency < 420000000)
    751		cp = 5;
    752	else if (tuner_frequency < 480000000)
    753		cp = 6;
    754	else if (tuner_frequency < 620000000)
    755		cp = 3;
    756	else if (tuner_frequency < 830000000)
    757		cp = 5;
    758	else if (tuner_frequency < 895000000)
    759		cp = 7;
    760	else
    761		return -EINVAL;
    762
    763	// determine band
    764	if (p->frequency < 49000000)
    765		return -EINVAL;
    766	else if (p->frequency < 159000000)
    767		band = 1;
    768	else if (p->frequency < 444000000)
    769		band = 2;
    770	else if (p->frequency < 861000000)
    771		band = 4;
    772	else
    773		return -EINVAL;
    774
    775	// setup PLL filter and TDA9889
    776	switch (p->bandwidth_hz) {
    777	case 6000000:
    778		tda1004x_writereg(fe, 0x0C, 0x14);
    779		filter = 0;
    780		break;
    781
    782	case 7000000:
    783		tda1004x_writereg(fe, 0x0C, 0x80);
    784		filter = 0;
    785		break;
    786
    787	case 8000000:
    788		tda1004x_writereg(fe, 0x0C, 0x14);
    789		filter = 1;
    790		break;
    791
    792	default:
    793		return -EINVAL;
    794	}
    795
    796	// calculate divisor
    797	// ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
    798	tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000;
    799
    800	// setup tuner buffer
    801	tuner_buf[0] = tuner_frequency >> 8;
    802	tuner_buf[1] = tuner_frequency & 0xff;
    803	tuner_buf[2] = 0xca;
    804	tuner_buf[3] = (cp << 5) | (filter << 3) | band;
    805
    806	if (fe->ops.i2c_gate_ctrl)
    807		fe->ops.i2c_gate_ctrl(fe, 1);
    808	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
    809		return -EIO;
    810
    811	msleep(1);
    812	return 0;
    813}
    814
    815static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
    816					     const struct firmware **fw, char *name)
    817{
    818	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
    819
    820	return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
    821}
    822
    823static struct tda1004x_config philips_tdm1316l_config = {
    824
    825	.demod_address = 0x8,
    826	.invert = 0,
    827	.invert_oclk = 0,
    828	.xtal_freq = TDA10046_XTAL_4M,
    829	.agc_config = TDA10046_AGC_DEFAULT,
    830	.if_freq = TDA10046_FREQ_3617,
    831	.request_firmware = philips_tdm1316l_request_firmware,
    832};
    833
    834static struct tda1004x_config philips_tdm1316l_config_invert = {
    835
    836	.demod_address = 0x8,
    837	.invert = 1,
    838	.invert_oclk = 0,
    839	.xtal_freq = TDA10046_XTAL_4M,
    840	.agc_config = TDA10046_AGC_DEFAULT,
    841	.if_freq = TDA10046_FREQ_3617,
    842	.request_firmware = philips_tdm1316l_request_firmware,
    843};
    844
    845static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
    846{
    847	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
    848	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
    849	u8 tuner_buf[5];
    850	struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
    851				    .flags = 0,
    852				    .buf = tuner_buf,
    853				    .len = sizeof(tuner_buf) };
    854	int tuner_frequency = 0;
    855	u8 band, cp, filter;
    856
    857	// determine charge pump
    858	tuner_frequency = p->frequency + 36125000;
    859	if (tuner_frequency < 87000000)
    860		return -EINVAL;
    861	else if (tuner_frequency < 130000000) {
    862		cp = 3;
    863		band = 1;
    864	} else if (tuner_frequency < 160000000) {
    865		cp = 5;
    866		band = 1;
    867	} else if (tuner_frequency < 200000000) {
    868		cp = 6;
    869		band = 1;
    870	} else if (tuner_frequency < 290000000) {
    871		cp = 3;
    872		band = 2;
    873	} else if (tuner_frequency < 420000000) {
    874		cp = 5;
    875		band = 2;
    876	} else if (tuner_frequency < 480000000) {
    877		cp = 6;
    878		band = 2;
    879	} else if (tuner_frequency < 620000000) {
    880		cp = 3;
    881		band = 4;
    882	} else if (tuner_frequency < 830000000) {
    883		cp = 5;
    884		band = 4;
    885	} else if (tuner_frequency < 895000000) {
    886		cp = 7;
    887		band = 4;
    888	} else
    889		return -EINVAL;
    890
    891	// assume PLL filter should always be 8MHz for the moment.
    892	filter = 1;
    893
    894	// calculate divisor
    895	tuner_frequency = (p->frequency + 36125000 + (62500/2)) / 62500;
    896
    897	// setup tuner buffer
    898	tuner_buf[0] = tuner_frequency >> 8;
    899	tuner_buf[1] = tuner_frequency & 0xff;
    900	tuner_buf[2] = 0xc8;
    901	tuner_buf[3] = (cp << 5) | (filter << 3) | band;
    902	tuner_buf[4] = 0x80;
    903
    904	if (fe->ops.i2c_gate_ctrl)
    905		fe->ops.i2c_gate_ctrl(fe, 1);
    906	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
    907		return -EIO;
    908
    909	msleep(50);
    910
    911	if (fe->ops.i2c_gate_ctrl)
    912		fe->ops.i2c_gate_ctrl(fe, 1);
    913	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
    914		return -EIO;
    915
    916	msleep(1);
    917
    918	return 0;
    919}
    920
    921static u8 dvbc_philips_tdm1316l_inittab[] = {
    922	0x80, 0x01,
    923	0x80, 0x00,
    924	0x81, 0x01,
    925	0x81, 0x00,
    926	0x00, 0x09,
    927	0x01, 0x69,
    928	0x03, 0x00,
    929	0x04, 0x00,
    930	0x07, 0x00,
    931	0x08, 0x00,
    932	0x20, 0x00,
    933	0x21, 0x40,
    934	0x22, 0x00,
    935	0x23, 0x00,
    936	0x24, 0x40,
    937	0x25, 0x88,
    938	0x30, 0xff,
    939	0x31, 0x00,
    940	0x32, 0xff,
    941	0x33, 0x00,
    942	0x34, 0x50,
    943	0x35, 0x7f,
    944	0x36, 0x00,
    945	0x37, 0x20,
    946	0x38, 0x00,
    947	0x40, 0x1c,
    948	0x41, 0xff,
    949	0x42, 0x29,
    950	0x43, 0x20,
    951	0x44, 0xff,
    952	0x45, 0x00,
    953	0x46, 0x00,
    954	0x49, 0x04,
    955	0x4a, 0x00,
    956	0x4b, 0x7b,
    957	0x52, 0x30,
    958	0x55, 0xae,
    959	0x56, 0x47,
    960	0x57, 0xe1,
    961	0x58, 0x3a,
    962	0x5a, 0x1e,
    963	0x5b, 0x34,
    964	0x60, 0x00,
    965	0x63, 0x00,
    966	0x64, 0x00,
    967	0x65, 0x00,
    968	0x66, 0x00,
    969	0x67, 0x00,
    970	0x68, 0x00,
    971	0x69, 0x00,
    972	0x6a, 0x02,
    973	0x6b, 0x00,
    974	0x70, 0xff,
    975	0x71, 0x00,
    976	0x72, 0x00,
    977	0x73, 0x00,
    978	0x74, 0x0c,
    979	0x80, 0x00,
    980	0x81, 0x00,
    981	0x82, 0x00,
    982	0x83, 0x00,
    983	0x84, 0x04,
    984	0x85, 0x80,
    985	0x86, 0x24,
    986	0x87, 0x78,
    987	0x88, 0x10,
    988	0x89, 0x00,
    989	0x90, 0x01,
    990	0x91, 0x01,
    991	0xa0, 0x04,
    992	0xa1, 0x00,
    993	0xa2, 0x00,
    994	0xb0, 0x91,
    995	0xb1, 0x0b,
    996	0xc0, 0x53,
    997	0xc1, 0x70,
    998	0xc2, 0x12,
    999	0xd0, 0x00,
   1000	0xd1, 0x00,
   1001	0xd2, 0x00,
   1002	0xd3, 0x00,
   1003	0xd4, 0x00,
   1004	0xd5, 0x00,
   1005	0xde, 0x00,
   1006	0xdf, 0x00,
   1007	0x61, 0x38,
   1008	0x62, 0x0a,
   1009	0x53, 0x13,
   1010	0x59, 0x08,
   1011	0xff, 0xff,
   1012};
   1013
   1014static struct stv0297_config dvbc_philips_tdm1316l_config = {
   1015	.demod_address = 0x1c,
   1016	.inittab = dvbc_philips_tdm1316l_inittab,
   1017	.invert = 0,
   1018	.stop_during_read = 1,
   1019};
   1020
   1021static struct tda10023_config tda10023_config = {
   1022	.demod_address = 0xc,
   1023	.invert = 0,
   1024	.xtal = 16000000,
   1025	.pll_m = 11,
   1026	.pll_p = 3,
   1027	.pll_n = 1,
   1028	.deltaf = 0xa511,
   1029};
   1030
   1031static struct tda827x_config tda827x_config = {
   1032	.config = 0,
   1033};
   1034
   1035/* TT S2-3200 DVB-S (STB0899) Inittab */
   1036static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
   1037
   1038	{ STB0899_DEV_ID		, 0x81 },
   1039	{ STB0899_DISCNTRL1		, 0x32 },
   1040	{ STB0899_DISCNTRL2		, 0x80 },
   1041	{ STB0899_DISRX_ST0		, 0x04 },
   1042	{ STB0899_DISRX_ST1		, 0x00 },
   1043	{ STB0899_DISPARITY		, 0x00 },
   1044	{ STB0899_DISSTATUS		, 0x20 },
   1045	{ STB0899_DISF22		, 0x8c },
   1046	{ STB0899_DISF22RX		, 0x9a },
   1047	{ STB0899_SYSREG		, 0x0b },
   1048	{ STB0899_ACRPRESC		, 0x11 },
   1049	{ STB0899_ACRDIV1		, 0x0a },
   1050	{ STB0899_ACRDIV2		, 0x05 },
   1051	{ STB0899_DACR1			, 0x00 },
   1052	{ STB0899_DACR2			, 0x00 },
   1053	{ STB0899_OUTCFG		, 0x00 },
   1054	{ STB0899_MODECFG		, 0x00 },
   1055	{ STB0899_IRQSTATUS_3		, 0x30 },
   1056	{ STB0899_IRQSTATUS_2		, 0x00 },
   1057	{ STB0899_IRQSTATUS_1		, 0x00 },
   1058	{ STB0899_IRQSTATUS_0		, 0x00 },
   1059	{ STB0899_IRQMSK_3		, 0xf3 },
   1060	{ STB0899_IRQMSK_2		, 0xfc },
   1061	{ STB0899_IRQMSK_1		, 0xff },
   1062	{ STB0899_IRQMSK_0		, 0xff },
   1063	{ STB0899_IRQCFG		, 0x00 },
   1064	{ STB0899_I2CCFG		, 0x88 },
   1065	{ STB0899_I2CRPT		, 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
   1066	{ STB0899_IOPVALUE5		, 0x00 },
   1067	{ STB0899_IOPVALUE4		, 0x20 },
   1068	{ STB0899_IOPVALUE3		, 0xc9 },
   1069	{ STB0899_IOPVALUE2		, 0x90 },
   1070	{ STB0899_IOPVALUE1		, 0x40 },
   1071	{ STB0899_IOPVALUE0		, 0x00 },
   1072	{ STB0899_GPIO00CFG		, 0x82 },
   1073	{ STB0899_GPIO01CFG		, 0x82 },
   1074	{ STB0899_GPIO02CFG		, 0x82 },
   1075	{ STB0899_GPIO03CFG		, 0x82 },
   1076	{ STB0899_GPIO04CFG		, 0x82 },
   1077	{ STB0899_GPIO05CFG		, 0x82 },
   1078	{ STB0899_GPIO06CFG		, 0x82 },
   1079	{ STB0899_GPIO07CFG		, 0x82 },
   1080	{ STB0899_GPIO08CFG		, 0x82 },
   1081	{ STB0899_GPIO09CFG		, 0x82 },
   1082	{ STB0899_GPIO10CFG		, 0x82 },
   1083	{ STB0899_GPIO11CFG		, 0x82 },
   1084	{ STB0899_GPIO12CFG		, 0x82 },
   1085	{ STB0899_GPIO13CFG		, 0x82 },
   1086	{ STB0899_GPIO14CFG		, 0x82 },
   1087	{ STB0899_GPIO15CFG		, 0x82 },
   1088	{ STB0899_GPIO16CFG		, 0x82 },
   1089	{ STB0899_GPIO17CFG		, 0x82 },
   1090	{ STB0899_GPIO18CFG		, 0x82 },
   1091	{ STB0899_GPIO19CFG		, 0x82 },
   1092	{ STB0899_GPIO20CFG		, 0x82 },
   1093	{ STB0899_SDATCFG		, 0xb8 },
   1094	{ STB0899_SCLTCFG		, 0xba },
   1095	{ STB0899_AGCRFCFG		, 0x1c }, /* 0x11 */
   1096	{ STB0899_GPIO22		, 0x82 }, /* AGCBB2CFG */
   1097	{ STB0899_GPIO21		, 0x91 }, /* AGCBB1CFG */
   1098	{ STB0899_DIRCLKCFG		, 0x82 },
   1099	{ STB0899_CLKOUT27CFG		, 0x7e },
   1100	{ STB0899_STDBYCFG		, 0x82 },
   1101	{ STB0899_CS0CFG		, 0x82 },
   1102	{ STB0899_CS1CFG		, 0x82 },
   1103	{ STB0899_DISEQCOCFG		, 0x20 },
   1104	{ STB0899_GPIO32CFG		, 0x82 },
   1105	{ STB0899_GPIO33CFG		, 0x82 },
   1106	{ STB0899_GPIO34CFG		, 0x82 },
   1107	{ STB0899_GPIO35CFG		, 0x82 },
   1108	{ STB0899_GPIO36CFG		, 0x82 },
   1109	{ STB0899_GPIO37CFG		, 0x82 },
   1110	{ STB0899_GPIO38CFG		, 0x82 },
   1111	{ STB0899_GPIO39CFG		, 0x82 },
   1112	{ STB0899_NCOARSE		, 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
   1113	{ STB0899_SYNTCTRL		, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
   1114	{ STB0899_FILTCTRL		, 0x00 },
   1115	{ STB0899_SYSCTRL		, 0x00 },
   1116	{ STB0899_STOPCLK1		, 0x20 },
   1117	{ STB0899_STOPCLK2		, 0x00 },
   1118	{ STB0899_INTBUFSTATUS		, 0x00 },
   1119	{ STB0899_INTBUFCTRL		, 0x0a },
   1120	{ 0xffff			, 0xff },
   1121};
   1122
   1123static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
   1124	{ STB0899_DEMOD			, 0x00 },
   1125	{ STB0899_RCOMPC		, 0xc9 },
   1126	{ STB0899_AGC1CN		, 0x41 },
   1127	{ STB0899_AGC1REF		, 0x10 },
   1128	{ STB0899_RTC			, 0x7a },
   1129	{ STB0899_TMGCFG		, 0x4e },
   1130	{ STB0899_AGC2REF		, 0x34 },
   1131	{ STB0899_TLSR			, 0x84 },
   1132	{ STB0899_CFD			, 0xc7 },
   1133	{ STB0899_ACLC			, 0x87 },
   1134	{ STB0899_BCLC			, 0x94 },
   1135	{ STB0899_EQON			, 0x41 },
   1136	{ STB0899_LDT			, 0xdd },
   1137	{ STB0899_LDT2			, 0xc9 },
   1138	{ STB0899_EQUALREF		, 0xb4 },
   1139	{ STB0899_TMGRAMP		, 0x10 },
   1140	{ STB0899_TMGTHD		, 0x30 },
   1141	{ STB0899_IDCCOMP		, 0xfb },
   1142	{ STB0899_QDCCOMP		, 0x03 },
   1143	{ STB0899_POWERI		, 0x3b },
   1144	{ STB0899_POWERQ		, 0x3d },
   1145	{ STB0899_RCOMP			, 0x81 },
   1146	{ STB0899_AGCIQIN		, 0x80 },
   1147	{ STB0899_AGC2I1		, 0x04 },
   1148	{ STB0899_AGC2I2		, 0xf5 },
   1149	{ STB0899_TLIR			, 0x25 },
   1150	{ STB0899_RTF			, 0x80 },
   1151	{ STB0899_DSTATUS		, 0x00 },
   1152	{ STB0899_LDI			, 0xca },
   1153	{ STB0899_CFRM			, 0xf1 },
   1154	{ STB0899_CFRL			, 0xf3 },
   1155	{ STB0899_NIRM			, 0x2a },
   1156	{ STB0899_NIRL			, 0x05 },
   1157	{ STB0899_ISYMB			, 0x17 },
   1158	{ STB0899_QSYMB			, 0xfa },
   1159	{ STB0899_SFRH			, 0x2f },
   1160	{ STB0899_SFRM			, 0x68 },
   1161	{ STB0899_SFRL			, 0x40 },
   1162	{ STB0899_SFRUPH		, 0x2f },
   1163	{ STB0899_SFRUPM		, 0x68 },
   1164	{ STB0899_SFRUPL		, 0x40 },
   1165	{ STB0899_EQUAI1		, 0xfd },
   1166	{ STB0899_EQUAQ1		, 0x04 },
   1167	{ STB0899_EQUAI2		, 0x0f },
   1168	{ STB0899_EQUAQ2		, 0xff },
   1169	{ STB0899_EQUAI3		, 0xdf },
   1170	{ STB0899_EQUAQ3		, 0xfa },
   1171	{ STB0899_EQUAI4		, 0x37 },
   1172	{ STB0899_EQUAQ4		, 0x0d },
   1173	{ STB0899_EQUAI5		, 0xbd },
   1174	{ STB0899_EQUAQ5		, 0xf7 },
   1175	{ STB0899_DSTATUS2		, 0x00 },
   1176	{ STB0899_VSTATUS		, 0x00 },
   1177	{ STB0899_VERROR		, 0xff },
   1178	{ STB0899_IQSWAP		, 0x2a },
   1179	{ STB0899_ECNT1M		, 0x00 },
   1180	{ STB0899_ECNT1L		, 0x00 },
   1181	{ STB0899_ECNT2M		, 0x00 },
   1182	{ STB0899_ECNT2L		, 0x00 },
   1183	{ STB0899_ECNT3M		, 0x00 },
   1184	{ STB0899_ECNT3L		, 0x00 },
   1185	{ STB0899_FECAUTO1		, 0x06 },
   1186	{ STB0899_FECM			, 0x01 },
   1187	{ STB0899_VTH12			, 0xf0 },
   1188	{ STB0899_VTH23			, 0xa0 },
   1189	{ STB0899_VTH34			, 0x78 },
   1190	{ STB0899_VTH56			, 0x4e },
   1191	{ STB0899_VTH67			, 0x48 },
   1192	{ STB0899_VTH78			, 0x38 },
   1193	{ STB0899_PRVIT			, 0xff },
   1194	{ STB0899_VITSYNC		, 0x19 },
   1195	{ STB0899_RSULC			, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
   1196	{ STB0899_TSULC			, 0x42 },
   1197	{ STB0899_RSLLC			, 0x40 },
   1198	{ STB0899_TSLPL			, 0x12 },
   1199	{ STB0899_TSCFGH		, 0x0c },
   1200	{ STB0899_TSCFGM		, 0x00 },
   1201	{ STB0899_TSCFGL		, 0x0c },
   1202	{ STB0899_TSOUT			, 0x4d }, /* 0x0d for CAM */
   1203	{ STB0899_RSSYNCDEL		, 0x00 },
   1204	{ STB0899_TSINHDELH		, 0x02 },
   1205	{ STB0899_TSINHDELM		, 0x00 },
   1206	{ STB0899_TSINHDELL		, 0x00 },
   1207	{ STB0899_TSLLSTKM		, 0x00 },
   1208	{ STB0899_TSLLSTKL		, 0x00 },
   1209	{ STB0899_TSULSTKM		, 0x00 },
   1210	{ STB0899_TSULSTKL		, 0xab },
   1211	{ STB0899_PCKLENUL		, 0x00 },
   1212	{ STB0899_PCKLENLL		, 0xcc },
   1213	{ STB0899_RSPCKLEN		, 0xcc },
   1214	{ STB0899_TSSTATUS		, 0x80 },
   1215	{ STB0899_ERRCTRL1		, 0xb6 },
   1216	{ STB0899_ERRCTRL2		, 0x96 },
   1217	{ STB0899_ERRCTRL3		, 0x89 },
   1218	{ STB0899_DMONMSK1		, 0x27 },
   1219	{ STB0899_DMONMSK0		, 0x03 },
   1220	{ STB0899_DEMAPVIT		, 0x5c },
   1221	{ STB0899_PLPARM		, 0x1f },
   1222	{ STB0899_PDELCTRL		, 0x48 },
   1223	{ STB0899_PDELCTRL2		, 0x00 },
   1224	{ STB0899_BBHCTRL1		, 0x00 },
   1225	{ STB0899_BBHCTRL2		, 0x00 },
   1226	{ STB0899_HYSTTHRESH		, 0x77 },
   1227	{ STB0899_MATCSTM		, 0x00 },
   1228	{ STB0899_MATCSTL		, 0x00 },
   1229	{ STB0899_UPLCSTM		, 0x00 },
   1230	{ STB0899_UPLCSTL		, 0x00 },
   1231	{ STB0899_DFLCSTM		, 0x00 },
   1232	{ STB0899_DFLCSTL		, 0x00 },
   1233	{ STB0899_SYNCCST		, 0x00 },
   1234	{ STB0899_SYNCDCSTM		, 0x00 },
   1235	{ STB0899_SYNCDCSTL		, 0x00 },
   1236	{ STB0899_ISI_ENTRY		, 0x00 },
   1237	{ STB0899_ISI_BIT_EN		, 0x00 },
   1238	{ STB0899_MATSTRM		, 0x00 },
   1239	{ STB0899_MATSTRL		, 0x00 },
   1240	{ STB0899_UPLSTRM		, 0x00 },
   1241	{ STB0899_UPLSTRL		, 0x00 },
   1242	{ STB0899_DFLSTRM		, 0x00 },
   1243	{ STB0899_DFLSTRL		, 0x00 },
   1244	{ STB0899_SYNCSTR		, 0x00 },
   1245	{ STB0899_SYNCDSTRM		, 0x00 },
   1246	{ STB0899_SYNCDSTRL		, 0x00 },
   1247	{ STB0899_CFGPDELSTATUS1	, 0x10 },
   1248	{ STB0899_CFGPDELSTATUS2	, 0x00 },
   1249	{ STB0899_BBFERRORM		, 0x00 },
   1250	{ STB0899_BBFERRORL		, 0x00 },
   1251	{ STB0899_UPKTERRORM		, 0x00 },
   1252	{ STB0899_UPKTERRORL		, 0x00 },
   1253	{ 0xffff			, 0xff },
   1254};
   1255
   1256static struct stb0899_config tt3200_config = {
   1257	.init_dev		= tt3200_stb0899_s1_init_1,
   1258	.init_s2_demod		= stb0899_s2_init_2,
   1259	.init_s1_demod		= tt3200_stb0899_s1_init_3,
   1260	.init_s2_fec		= stb0899_s2_init_4,
   1261	.init_tst		= stb0899_s1_init_5,
   1262
   1263	.postproc		= NULL,
   1264
   1265	.demod_address		= 0x68,
   1266
   1267	.xtal_freq		= 27000000,
   1268	.inversion		= IQ_SWAP_ON,
   1269
   1270	.lo_clk			= 76500000,
   1271	.hi_clk			= 99000000,
   1272
   1273	.esno_ave		= STB0899_DVBS2_ESNO_AVE,
   1274	.esno_quant		= STB0899_DVBS2_ESNO_QUANT,
   1275	.avframes_coarse	= STB0899_DVBS2_AVFRAMES_COARSE,
   1276	.avframes_fine		= STB0899_DVBS2_AVFRAMES_FINE,
   1277	.miss_threshold		= STB0899_DVBS2_MISS_THRESHOLD,
   1278	.uwp_threshold_acq	= STB0899_DVBS2_UWP_THRESHOLD_ACQ,
   1279	.uwp_threshold_track	= STB0899_DVBS2_UWP_THRESHOLD_TRACK,
   1280	.uwp_threshold_sof	= STB0899_DVBS2_UWP_THRESHOLD_SOF,
   1281	.sof_search_timeout	= STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
   1282
   1283	.btr_nco_bits		= STB0899_DVBS2_BTR_NCO_BITS,
   1284	.btr_gain_shift_offset	= STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
   1285	.crl_nco_bits		= STB0899_DVBS2_CRL_NCO_BITS,
   1286	.ldpc_max_iter		= STB0899_DVBS2_LDPC_MAX_ITER,
   1287
   1288	.tuner_get_frequency	= stb6100_get_frequency,
   1289	.tuner_set_frequency	= stb6100_set_frequency,
   1290	.tuner_set_bandwidth	= stb6100_set_bandwidth,
   1291	.tuner_get_bandwidth	= stb6100_get_bandwidth,
   1292	.tuner_set_rfsiggain	= NULL
   1293};
   1294
   1295static struct stb6100_config tt3200_stb6100_config = {
   1296	.tuner_address	= 0x60,
   1297	.refclock	= 27000000,
   1298};
   1299
   1300static void frontend_init(struct budget_ci *budget_ci)
   1301{
   1302	switch (budget_ci->budget.dev->pci->subsystem_device) {
   1303	case 0x100c:		// Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
   1304		budget_ci->budget.dvb_frontend =
   1305			dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
   1306		if (budget_ci->budget.dvb_frontend) {
   1307			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
   1308			budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
   1309			break;
   1310		}
   1311		break;
   1312
   1313	case 0x100f:		// Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
   1314		budget_ci->budget.dvb_frontend =
   1315			dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
   1316		if (budget_ci->budget.dvb_frontend) {
   1317			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
   1318			break;
   1319		}
   1320		break;
   1321
   1322	case 0x1010:		// TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
   1323		budget_ci->tuner_pll_address = 0x61;
   1324		budget_ci->budget.dvb_frontend =
   1325			dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
   1326		if (budget_ci->budget.dvb_frontend) {
   1327			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
   1328			break;
   1329		}
   1330		break;
   1331
   1332	case 0x1011:		// Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
   1333		budget_ci->tuner_pll_address = 0x63;
   1334		budget_ci->budget.dvb_frontend =
   1335			dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
   1336		if (budget_ci->budget.dvb_frontend) {
   1337			budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
   1338			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
   1339			break;
   1340		}
   1341		break;
   1342
   1343	case 0x1012:		// TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
   1344		budget_ci->tuner_pll_address = 0x60;
   1345		budget_ci->budget.dvb_frontend =
   1346			dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
   1347		if (budget_ci->budget.dvb_frontend) {
   1348			budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
   1349			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
   1350			break;
   1351		}
   1352		break;
   1353
   1354	case 0x1017:		// TT S-1500 PCI
   1355		budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
   1356		if (budget_ci->budget.dvb_frontend) {
   1357			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
   1358			budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
   1359
   1360			budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
   1361			if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
   1362				printk("%s: No LNBP21 found!\n", __func__);
   1363				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
   1364				budget_ci->budget.dvb_frontend = NULL;
   1365			}
   1366		}
   1367		break;
   1368
   1369	case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
   1370		budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
   1371		if (budget_ci->budget.dvb_frontend) {
   1372			if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
   1373				printk(KERN_ERR "%s: No tda827x found!\n", __func__);
   1374				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
   1375				budget_ci->budget.dvb_frontend = NULL;
   1376			}
   1377		}
   1378		break;
   1379
   1380	case 0x101b: /* TT S-1500B (BSBE1-D01A - STV0288/STB6000/LNBP21) */
   1381		budget_ci->budget.dvb_frontend = dvb_attach(stv0288_attach, &stv0288_bsbe1_d01a_config, &budget_ci->budget.i2c_adap);
   1382		if (budget_ci->budget.dvb_frontend) {
   1383			if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) {
   1384				if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
   1385					printk(KERN_ERR "%s: No LNBP21 found!\n", __func__);
   1386					dvb_frontend_detach(budget_ci->budget.dvb_frontend);
   1387					budget_ci->budget.dvb_frontend = NULL;
   1388				}
   1389			} else {
   1390				printk(KERN_ERR "%s: No STB6000 found!\n", __func__);
   1391				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
   1392				budget_ci->budget.dvb_frontend = NULL;
   1393			}
   1394		}
   1395		break;
   1396
   1397	case 0x1019:		// TT S2-3200 PCI
   1398		/*
   1399		 * NOTE! on some STB0899 versions, the internal PLL takes a longer time
   1400		 * to settle, aka LOCK. On the older revisions of the chip, we don't see
   1401		 * this, as a result on the newer chips the entire clock tree, will not
   1402		 * be stable after a freshly POWER 'ed up situation.
   1403		 * In this case, we should RESET the STB0899 (Active LOW) and wait for
   1404		 * PLL stabilization.
   1405		 *
   1406		 * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is
   1407		 * connected to the SAA7146 GPIO, GPIO2, Pin 142
   1408		 */
   1409		/* Reset Demodulator */
   1410		saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
   1411		/* Wait for everything to die */
   1412		msleep(50);
   1413		/* Pull it up out of Reset state */
   1414		saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
   1415		/* Wait for PLL to stabilize */
   1416		msleep(250);
   1417		/*
   1418		 * PLL state should be stable now. Ideally, we should check
   1419		 * for PLL LOCK status. But well, never mind!
   1420		 */
   1421		budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
   1422		if (budget_ci->budget.dvb_frontend) {
   1423			if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
   1424				if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
   1425					printk("%s: No LNBP21 found!\n", __func__);
   1426					dvb_frontend_detach(budget_ci->budget.dvb_frontend);
   1427					budget_ci->budget.dvb_frontend = NULL;
   1428				}
   1429			} else {
   1430					dvb_frontend_detach(budget_ci->budget.dvb_frontend);
   1431					budget_ci->budget.dvb_frontend = NULL;
   1432			}
   1433		}
   1434		break;
   1435
   1436	}
   1437
   1438	if (budget_ci->budget.dvb_frontend == NULL) {
   1439		printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
   1440		       budget_ci->budget.dev->pci->vendor,
   1441		       budget_ci->budget.dev->pci->device,
   1442		       budget_ci->budget.dev->pci->subsystem_vendor,
   1443		       budget_ci->budget.dev->pci->subsystem_device);
   1444	} else {
   1445		if (dvb_register_frontend
   1446		    (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
   1447			printk("budget-ci: Frontend registration failed!\n");
   1448			dvb_frontend_detach(budget_ci->budget.dvb_frontend);
   1449			budget_ci->budget.dvb_frontend = NULL;
   1450		}
   1451	}
   1452}
   1453
   1454static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
   1455{
   1456	struct budget_ci *budget_ci;
   1457	int err;
   1458
   1459	budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
   1460	if (!budget_ci) {
   1461		err = -ENOMEM;
   1462		goto out1;
   1463	}
   1464
   1465	dprintk(2, "budget_ci: %p\n", budget_ci);
   1466
   1467	dev->ext_priv = budget_ci;
   1468
   1469	err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
   1470				adapter_nr);
   1471	if (err)
   1472		goto out2;
   1473
   1474	err = msp430_ir_init(budget_ci);
   1475	if (err)
   1476		goto out3;
   1477
   1478	ciintf_init(budget_ci);
   1479
   1480	budget_ci->budget.dvb_adapter.priv = budget_ci;
   1481	frontend_init(budget_ci);
   1482
   1483	ttpci_budget_init_hooks(&budget_ci->budget);
   1484
   1485	return 0;
   1486
   1487out3:
   1488	ttpci_budget_deinit(&budget_ci->budget);
   1489out2:
   1490	kfree(budget_ci);
   1491out1:
   1492	return err;
   1493}
   1494
   1495static int budget_ci_detach(struct saa7146_dev *dev)
   1496{
   1497	struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
   1498	struct saa7146_dev *saa = budget_ci->budget.dev;
   1499	int err;
   1500
   1501	if (budget_ci->budget.ci_present)
   1502		ciintf_deinit(budget_ci);
   1503	msp430_ir_deinit(budget_ci);
   1504	if (budget_ci->budget.dvb_frontend) {
   1505		dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
   1506		dvb_frontend_detach(budget_ci->budget.dvb_frontend);
   1507	}
   1508	err = ttpci_budget_deinit(&budget_ci->budget);
   1509
   1510	// disable frontend and CI interface
   1511	saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
   1512
   1513	kfree(budget_ci);
   1514
   1515	return err;
   1516}
   1517
   1518static struct saa7146_extension budget_extension;
   1519
   1520MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
   1521MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
   1522MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T	 PCI", BUDGET_TT);
   1523MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
   1524MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
   1525MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
   1526MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
   1527MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT);
   1528
   1529static const struct pci_device_id pci_tbl[] = {
   1530	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
   1531	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
   1532	MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
   1533	MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
   1534	MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
   1535	MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
   1536	MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
   1537	MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
   1538	MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b),
   1539	{
   1540	 .vendor = 0,
   1541	 }
   1542};
   1543
   1544MODULE_DEVICE_TABLE(pci, pci_tbl);
   1545
   1546static struct saa7146_extension budget_extension = {
   1547	.name = "budget_ci dvb",
   1548	.flags = SAA7146_USE_I2C_IRQ,
   1549
   1550	.module = THIS_MODULE,
   1551	.pci_tbl = &pci_tbl[0],
   1552	.attach = budget_ci_attach,
   1553	.detach = budget_ci_detach,
   1554
   1555	.irq_mask = MASK_03 | MASK_06 | MASK_10,
   1556	.irq_func = budget_ci_irq,
   1557};
   1558
   1559static int __init budget_ci_init(void)
   1560{
   1561	return saa7146_register_extension(&budget_extension);
   1562}
   1563
   1564static void __exit budget_ci_exit(void)
   1565{
   1566	saa7146_unregister_extension(&budget_extension);
   1567}
   1568
   1569module_init(budget_ci_init);
   1570module_exit(budget_ci_exit);
   1571
   1572MODULE_LICENSE("GPL");
   1573MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
   1574MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards w/ CI-module produced by Siemens, Technotrend, Hauppauge");