xref: /linux/drivers/media/pci/ttpci/budget-ci.c (revision dccc0c3ddf8f16071736f98a7d6dd46a2d43e037)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * budget-ci.ko: driver for the SAA7146 based Budget DVB cards
4  *               with CI (but without analog video input)
5  *
6  * Compiled from various sources by Michael Hunold <michael@mihu.de>
7  *
8  *     msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
9  *     partially based on the Siemens DVB driver by Ralph+Marcus Metzler
10  *
11  * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
12  *
13  * the project's page is at https://linuxtv.org
14  */
15 
16 #include <linux/module.h>
17 #include <linux/errno.h>
18 #include <linux/slab.h>
19 #include <linux/interrupt.h>
20 #include <linux/spinlock.h>
21 #include <linux/workqueue.h>
22 #include <media/rc-core.h>
23 
24 #include "budget.h"
25 
26 #include <media/dvb_ca_en50221.h>
27 #include "stv0299.h"
28 #include "stv0297.h"
29 #include "tda1004x.h"
30 #include "stb0899_drv.h"
31 #include "stb0899_reg.h"
32 #include "stb0899_cfg.h"
33 #include "stb6100.h"
34 #include "stb6100_cfg.h"
35 #include "lnbp21.h"
36 #include "bsbe1.h"
37 #include "bsru6.h"
38 #include "tda1002x.h"
39 #include "tda827x.h"
40 #include "bsbe1-d01a.h"
41 
42 #define MODULE_NAME "budget_ci"
43 
44 /*
45  * Regarding DEBIADDR_IR:
46  * Some CI modules hang if random addresses are read.
47  * Using address 0x4000 for the IR read means that we
48  * use the same address as for CI version, which should
49  * be a safe default.
50  */
51 #define DEBIADDR_IR		0x4000
52 #define DEBIADDR_CICONTROL	0x0000
53 #define DEBIADDR_CIVERSION	0x4000
54 #define DEBIADDR_IO		0x1000
55 #define DEBIADDR_ATTR		0x3000
56 
57 #define CICONTROL_RESET		0x01
58 #define CICONTROL_ENABLETS	0x02
59 #define CICONTROL_CAMDETECT	0x08
60 
61 #define DEBICICTL		0x00420000
62 #define DEBICICAM		0x02420000
63 
64 #define SLOTSTATUS_NONE		1
65 #define SLOTSTATUS_PRESENT	2
66 #define SLOTSTATUS_RESET	4
67 #define SLOTSTATUS_READY	8
68 #define SLOTSTATUS_OCCUPIED	(SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
69 
70 /* RC5 device wildcard */
71 #define IR_DEVICE_ANY		255
72 
73 static int rc5_device = -1;
74 module_param(rc5_device, int, 0644);
75 MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
76 
77 static int ir_debug;
78 module_param(ir_debug, int, 0644);
79 MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
80 
81 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
82 
83 struct budget_ci_ir {
84 	struct rc_dev *dev;
85 	struct work_struct msp430_irq_bh_work;
86 	char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
87 	char phys[32];
88 	int rc5_device;
89 	u32 ir_key;
90 	bool have_command;
91 	bool full_rc5;		/* Outputs a full RC5 code */
92 };
93 
94 struct budget_ci {
95 	struct budget budget;
96 	struct work_struct ciintf_irq_bh_work;
97 	int slot_status;
98 	int ci_irq;
99 	struct dvb_ca_en50221 ca;
100 	struct budget_ci_ir ir;
101 	u8 tuner_pll_address; /* used for philips_tdm1316l configs */
102 };
103 
104 static void msp430_ir_interrupt(struct work_struct *t)
105 {
106 	struct budget_ci_ir *ir = from_work(ir, t, msp430_irq_bh_work);
107 	struct budget_ci *budget_ci = container_of(ir, typeof(*budget_ci), ir);
108 	struct rc_dev *dev = budget_ci->ir.dev;
109 	u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
110 
111 	/*
112 	 * The msp430 chip can generate two different bytes, command and device
113 	 *
114 	 * type1: X1CCCCCC, C = command bits (0 - 63)
115 	 * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
116 	 *
117 	 * Each signal from the remote control can generate one or more command
118 	 * bytes and one or more device bytes. For the repeated bytes, the
119 	 * highest bit (X) is set. The first command byte is always generated
120 	 * before the first device byte. Other than that, no specific order
121 	 * seems to apply. To make life interesting, bytes can also be lost.
122 	 *
123 	 * Only when we have a command and device byte, a keypress is
124 	 * generated.
125 	 */
126 
127 	if (ir_debug)
128 		pr_info("received byte 0x%02x\n", command);
129 
130 	/* Remove repeat bit, we use every command */
131 	command = command & 0x7f;
132 
133 	/* Is this a RC5 command byte? */
134 	if (command & 0x40) {
135 		budget_ci->ir.have_command = true;
136 		budget_ci->ir.ir_key = command & 0x3f;
137 		return;
138 	}
139 
140 	/* It's a RC5 device byte */
141 	if (!budget_ci->ir.have_command)
142 		return;
143 	budget_ci->ir.have_command = false;
144 
145 	if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
146 	    budget_ci->ir.rc5_device != (command & 0x1f))
147 		return;
148 
149 	if (budget_ci->ir.full_rc5) {
150 		rc_keydown(dev, RC_PROTO_RC5,
151 			   RC_SCANCODE_RC5(budget_ci->ir.rc5_device, budget_ci->ir.ir_key),
152 			   !!(command & 0x20));
153 		return;
154 	}
155 
156 	/* FIXME: We should generate complete scancodes for all devices */
157 	rc_keydown(dev, RC_PROTO_UNKNOWN, budget_ci->ir.ir_key,
158 		   !!(command & 0x20));
159 }
160 
161 static int msp430_ir_init(struct budget_ci *budget_ci)
162 {
163 	struct saa7146_dev *saa = budget_ci->budget.dev;
164 	struct rc_dev *dev;
165 	int error;
166 
167 	dev = rc_allocate_device(RC_DRIVER_SCANCODE);
168 	if (!dev) {
169 		pr_err("IR interface initialisation failed\n");
170 		return -ENOMEM;
171 	}
172 
173 	snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
174 		 "Budget-CI dvb ir receiver %s", saa->name);
175 	snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
176 		 "pci-%s/ir0", pci_name(saa->pci));
177 
178 	dev->driver_name = MODULE_NAME;
179 	dev->device_name = budget_ci->ir.name;
180 	dev->input_phys = budget_ci->ir.phys;
181 	dev->input_id.bustype = BUS_PCI;
182 	dev->input_id.version = 1;
183 	if (saa->pci->subsystem_vendor) {
184 		dev->input_id.vendor = saa->pci->subsystem_vendor;
185 		dev->input_id.product = saa->pci->subsystem_device;
186 	} else {
187 		dev->input_id.vendor = saa->pci->vendor;
188 		dev->input_id.product = saa->pci->device;
189 	}
190 	dev->dev.parent = &saa->pci->dev;
191 
192 	if (rc5_device < 0)
193 		budget_ci->ir.rc5_device = IR_DEVICE_ANY;
194 	else
195 		budget_ci->ir.rc5_device = rc5_device;
196 
197 	/* Select keymap and address */
198 	switch (budget_ci->budget.dev->pci->subsystem_device) {
199 	case 0x100c:
200 	case 0x100f:
201 	case 0x1011:
202 	case 0x1012:
203 		/* The hauppauge keymap is a superset of these remotes */
204 		dev->map_name = RC_MAP_HAUPPAUGE;
205 		budget_ci->ir.full_rc5 = true;
206 
207 		if (rc5_device < 0)
208 			budget_ci->ir.rc5_device = 0x1f;
209 		break;
210 	case 0x1010:
211 	case 0x1017:
212 	case 0x1019:
213 	case 0x101a:
214 	case 0x101b:
215 		/* for the Technotrend 1500 bundled remote */
216 		dev->map_name = RC_MAP_TT_1500;
217 		break;
218 	default:
219 		/* unknown remote */
220 		dev->map_name = RC_MAP_BUDGET_CI_OLD;
221 		break;
222 	}
223 	if (!budget_ci->ir.full_rc5)
224 		dev->scancode_mask = 0xff;
225 
226 	error = rc_register_device(dev);
227 	if (error) {
228 		pr_err("could not init driver for IR device (code %d)\n", error);
229 		rc_free_device(dev);
230 		return error;
231 	}
232 
233 	budget_ci->ir.dev = dev;
234 
235 	INIT_WORK(&budget_ci->ir.msp430_irq_bh_work, msp430_ir_interrupt);
236 
237 	SAA7146_IER_ENABLE(saa, MASK_06);
238 	saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
239 
240 	return 0;
241 }
242 
243 static void msp430_ir_deinit(struct budget_ci *budget_ci)
244 {
245 	struct saa7146_dev *saa = budget_ci->budget.dev;
246 
247 	SAA7146_IER_DISABLE(saa, MASK_06);
248 	saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
249 	cancel_work_sync(&budget_ci->ir.msp430_irq_bh_work);
250 
251 	rc_unregister_device(budget_ci->ir.dev);
252 	rc_free_device(budget_ci->ir.dev);
253 }
254 
255 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
256 {
257 	struct budget_ci *budget_ci = ca->data;
258 
259 	if (slot != 0)
260 		return -EINVAL;
261 
262 	return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
263 				     DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
264 }
265 
266 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
267 {
268 	struct budget_ci *budget_ci = ca->data;
269 
270 	if (slot != 0)
271 		return -EINVAL;
272 
273 	return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
274 				      DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
275 }
276 
277 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
278 {
279 	struct budget_ci *budget_ci = ca->data;
280 
281 	if (slot != 0)
282 		return -EINVAL;
283 
284 	return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
285 				     DEBIADDR_IO | (address & 3), 1, 1, 0);
286 }
287 
288 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
289 {
290 	struct budget_ci *budget_ci = ca->data;
291 
292 	if (slot != 0)
293 		return -EINVAL;
294 
295 	return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
296 				      DEBIADDR_IO | (address & 3), 1, value, 1, 0);
297 }
298 
299 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
300 {
301 	struct budget_ci *budget_ci = ca->data;
302 	struct saa7146_dev *saa = budget_ci->budget.dev;
303 
304 	if (slot != 0)
305 		return -EINVAL;
306 
307 	if (budget_ci->ci_irq) {
308 		// trigger on RISING edge during reset so we know when READY is re-asserted
309 		saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
310 	}
311 	budget_ci->slot_status = SLOTSTATUS_RESET;
312 	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
313 	msleep(1);
314 	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
315 			       CICONTROL_RESET, 1, 0);
316 
317 	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
318 	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
319 	return 0;
320 }
321 
322 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
323 {
324 	struct budget_ci *budget_ci = ca->data;
325 	struct saa7146_dev *saa = budget_ci->budget.dev;
326 
327 	if (slot != 0)
328 		return -EINVAL;
329 
330 	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
331 	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
332 	return 0;
333 }
334 
335 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
336 {
337 	struct budget_ci *budget_ci = ca->data;
338 	struct saa7146_dev *saa = budget_ci->budget.dev;
339 	int tmp;
340 
341 	if (slot != 0)
342 		return -EINVAL;
343 
344 	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
345 
346 	tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
347 	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
348 			       tmp | CICONTROL_ENABLETS, 1, 0);
349 
350 	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
351 	return 0;
352 }
353 
354 static void ciintf_interrupt(struct work_struct *t)
355 {
356 	struct budget_ci *budget_ci = from_work(budget_ci, t,
357 						   ciintf_irq_bh_work);
358 	struct saa7146_dev *saa = budget_ci->budget.dev;
359 	unsigned int flags;
360 
361 	// ensure we don't get spurious IRQs during initialisation
362 	if (!budget_ci->budget.ci_present)
363 		return;
364 
365 	// read the CAM status
366 	flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
367 	if (flags & CICONTROL_CAMDETECT) {
368 
369 		// GPIO should be set to trigger on falling edge if a CAM is present
370 		saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
371 
372 		if (budget_ci->slot_status & SLOTSTATUS_NONE) {
373 			// CAM insertion IRQ
374 			budget_ci->slot_status = SLOTSTATUS_PRESENT;
375 			dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
376 						     DVB_CA_EN50221_CAMCHANGE_INSERTED);
377 
378 		} else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
379 			// CAM ready (reset completed)
380 			budget_ci->slot_status = SLOTSTATUS_READY;
381 			dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
382 
383 		} else if (budget_ci->slot_status & SLOTSTATUS_READY) {
384 			// FR/DA IRQ
385 			dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
386 		}
387 	} else {
388 
389 		// trigger on rising edge if a CAM is not present - when a CAM is inserted, we
390 		// only want to get the IRQ when it sets READY. If we trigger on the falling edge,
391 		// the CAM might not actually be ready yet.
392 		saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
393 
394 		// generate a CAM removal IRQ if we haven't already
395 		if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
396 			// CAM removal IRQ
397 			budget_ci->slot_status = SLOTSTATUS_NONE;
398 			dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
399 						     DVB_CA_EN50221_CAMCHANGE_REMOVED);
400 		}
401 	}
402 }
403 
404 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
405 {
406 	struct budget_ci *budget_ci = ca->data;
407 	unsigned int flags;
408 
409 	// ensure we don't get spurious IRQs during initialisation
410 	if (!budget_ci->budget.ci_present)
411 		return -EINVAL;
412 
413 	// read the CAM status
414 	flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
415 	if (flags & CICONTROL_CAMDETECT) {
416 		// mark it as present if it wasn't before
417 		if (budget_ci->slot_status & SLOTSTATUS_NONE)
418 			budget_ci->slot_status = SLOTSTATUS_PRESENT;
419 
420 		// during a RESET, we check if we can read from IO memory to see when CAM is ready
421 		if (budget_ci->slot_status & SLOTSTATUS_RESET) {
422 			if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d)
423 				budget_ci->slot_status = SLOTSTATUS_READY;
424 		}
425 	} else {
426 		budget_ci->slot_status = SLOTSTATUS_NONE;
427 	}
428 
429 	if (budget_ci->slot_status != SLOTSTATUS_NONE) {
430 		if (budget_ci->slot_status & SLOTSTATUS_READY)
431 			return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
432 		return DVB_CA_EN50221_POLL_CAM_PRESENT;
433 	}
434 
435 	return 0;
436 }
437 
438 static 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 
487 	result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
488 				     &budget_ci->ca, ca_flags, 1);
489 	if (result != 0) {
490 		pr_err("CI interface detected, but initialisation failed.\n");
491 		goto error;
492 	}
493 
494 	// Setup CI slot IRQ
495 	if (budget_ci->ci_irq) {
496 		INIT_WORK(&budget_ci->ciintf_irq_bh_work, ciintf_interrupt);
497 		if (budget_ci->slot_status != SLOTSTATUS_NONE)
498 			saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
499 		else
500 			saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
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 	pr_info("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 
522 error:
523 	saa7146_write(saa, MC1, MASK_27);
524 	return result;
525 }
526 
527 static 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 		cancel_work_sync(&budget_ci->ciintf_irq_bh_work);
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 
554 static void budget_ci_irq(struct saa7146_dev *dev, u32 *isr)
555 {
556 	struct budget_ci *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 		queue_work(system_bh_wq, &budget_ci->ir.msp430_irq_bh_work);
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 		queue_work(system_bh_wq, &budget_ci->ciintf_irq_bh_work);
568 }
569 
570 static 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 
616 static 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 
648 static 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 = 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 
684 static 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 
699 static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
700 {
701 	struct budget_ci *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 
729 static 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 = 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 
815 static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
816 					     const struct firmware **fw, char *name)
817 {
818 	struct budget_ci *budget_ci = fe->dvb->priv;
819 
820 	return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
821 }
822 
823 static 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 
834 static 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 
845 static 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 = 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 
892 	// assume PLL filter should always be 8MHz for the moment.
893 	filter = 1;
894 
895 	// calculate divisor
896 	tuner_frequency = (p->frequency + 36125000 + (62500/2)) / 62500;
897 
898 	// setup tuner buffer
899 	tuner_buf[0] = tuner_frequency >> 8;
900 	tuner_buf[1] = tuner_frequency & 0xff;
901 	tuner_buf[2] = 0xc8;
902 	tuner_buf[3] = (cp << 5) | (filter << 3) | band;
903 	tuner_buf[4] = 0x80;
904 
905 	if (fe->ops.i2c_gate_ctrl)
906 		fe->ops.i2c_gate_ctrl(fe, 1);
907 	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
908 		return -EIO;
909 
910 	msleep(50);
911 
912 	if (fe->ops.i2c_gate_ctrl)
913 		fe->ops.i2c_gate_ctrl(fe, 1);
914 	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
915 		return -EIO;
916 
917 	msleep(1);
918 
919 	return 0;
920 }
921 
922 static u8 dvbc_philips_tdm1316l_inittab[] = {
923 	0x80, 0x01,
924 	0x80, 0x00,
925 	0x81, 0x01,
926 	0x81, 0x00,
927 	0x00, 0x09,
928 	0x01, 0x69,
929 	0x03, 0x00,
930 	0x04, 0x00,
931 	0x07, 0x00,
932 	0x08, 0x00,
933 	0x20, 0x00,
934 	0x21, 0x40,
935 	0x22, 0x00,
936 	0x23, 0x00,
937 	0x24, 0x40,
938 	0x25, 0x88,
939 	0x30, 0xff,
940 	0x31, 0x00,
941 	0x32, 0xff,
942 	0x33, 0x00,
943 	0x34, 0x50,
944 	0x35, 0x7f,
945 	0x36, 0x00,
946 	0x37, 0x20,
947 	0x38, 0x00,
948 	0x40, 0x1c,
949 	0x41, 0xff,
950 	0x42, 0x29,
951 	0x43, 0x20,
952 	0x44, 0xff,
953 	0x45, 0x00,
954 	0x46, 0x00,
955 	0x49, 0x04,
956 	0x4a, 0x00,
957 	0x4b, 0x7b,
958 	0x52, 0x30,
959 	0x55, 0xae,
960 	0x56, 0x47,
961 	0x57, 0xe1,
962 	0x58, 0x3a,
963 	0x5a, 0x1e,
964 	0x5b, 0x34,
965 	0x60, 0x00,
966 	0x63, 0x00,
967 	0x64, 0x00,
968 	0x65, 0x00,
969 	0x66, 0x00,
970 	0x67, 0x00,
971 	0x68, 0x00,
972 	0x69, 0x00,
973 	0x6a, 0x02,
974 	0x6b, 0x00,
975 	0x70, 0xff,
976 	0x71, 0x00,
977 	0x72, 0x00,
978 	0x73, 0x00,
979 	0x74, 0x0c,
980 	0x80, 0x00,
981 	0x81, 0x00,
982 	0x82, 0x00,
983 	0x83, 0x00,
984 	0x84, 0x04,
985 	0x85, 0x80,
986 	0x86, 0x24,
987 	0x87, 0x78,
988 	0x88, 0x10,
989 	0x89, 0x00,
990 	0x90, 0x01,
991 	0x91, 0x01,
992 	0xa0, 0x04,
993 	0xa1, 0x00,
994 	0xa2, 0x00,
995 	0xb0, 0x91,
996 	0xb1, 0x0b,
997 	0xc0, 0x53,
998 	0xc1, 0x70,
999 	0xc2, 0x12,
1000 	0xd0, 0x00,
1001 	0xd1, 0x00,
1002 	0xd2, 0x00,
1003 	0xd3, 0x00,
1004 	0xd4, 0x00,
1005 	0xd5, 0x00,
1006 	0xde, 0x00,
1007 	0xdf, 0x00,
1008 	0x61, 0x38,
1009 	0x62, 0x0a,
1010 	0x53, 0x13,
1011 	0x59, 0x08,
1012 	0xff, 0xff,
1013 };
1014 
1015 static struct stv0297_config dvbc_philips_tdm1316l_config = {
1016 	.demod_address = 0x1c,
1017 	.inittab = dvbc_philips_tdm1316l_inittab,
1018 	.invert = 0,
1019 	.stop_during_read = 1,
1020 };
1021 
1022 static struct tda10023_config tda10023_config = {
1023 	.demod_address = 0xc,
1024 	.invert = 0,
1025 	.xtal = 16000000,
1026 	.pll_m = 11,
1027 	.pll_p = 3,
1028 	.pll_n = 1,
1029 	.deltaf = 0xa511,
1030 };
1031 
1032 static struct tda827x_config tda827x_config = {
1033 	.config = 0,
1034 };
1035 
1036 /* TT S2-3200 DVB-S (STB0899) Inittab */
1037 static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
1038 
1039 	{ STB0899_DEV_ID,		0x81 },
1040 	{ STB0899_DISCNTRL1,		0x32 },
1041 	{ STB0899_DISCNTRL2,		0x80 },
1042 	{ STB0899_DISRX_ST0,		0x04 },
1043 	{ STB0899_DISRX_ST1,		0x00 },
1044 	{ STB0899_DISPARITY,		0x00 },
1045 	{ STB0899_DISSTATUS,		0x20 },
1046 	{ STB0899_DISF22,		0x8c },
1047 	{ STB0899_DISF22RX,		0x9a },
1048 	{ STB0899_SYSREG,		0x0b },
1049 	{ STB0899_ACRPRESC,		0x11 },
1050 	{ STB0899_ACRDIV1,		0x0a },
1051 	{ STB0899_ACRDIV2,		0x05 },
1052 	{ STB0899_DACR1,		0x00 },
1053 	{ STB0899_DACR2,		0x00 },
1054 	{ STB0899_OUTCFG,		0x00 },
1055 	{ STB0899_MODECFG,		0x00 },
1056 	{ STB0899_IRQSTATUS_3,		0x30 },
1057 	{ STB0899_IRQSTATUS_2,		0x00 },
1058 	{ STB0899_IRQSTATUS_1,		0x00 },
1059 	{ STB0899_IRQSTATUS_0,		0x00 },
1060 	{ STB0899_IRQMSK_3,		0xf3 },
1061 	{ STB0899_IRQMSK_2,		0xfc },
1062 	{ STB0899_IRQMSK_1,		0xff },
1063 	{ STB0899_IRQMSK_0,		0xff },
1064 	{ STB0899_IRQCFG,		0x00 },
1065 	{ STB0899_I2CCFG,		0x88 },
1066 	{ STB0899_I2CRPT,		0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
1067 	{ STB0899_IOPVALUE5,		0x00 },
1068 	{ STB0899_IOPVALUE4,		0x20 },
1069 	{ STB0899_IOPVALUE3,		0xc9 },
1070 	{ STB0899_IOPVALUE2,		0x90 },
1071 	{ STB0899_IOPVALUE1,		0x40 },
1072 	{ STB0899_IOPVALUE0,		0x00 },
1073 	{ STB0899_GPIO00CFG,		0x82 },
1074 	{ STB0899_GPIO01CFG,		0x82 },
1075 	{ STB0899_GPIO02CFG,		0x82 },
1076 	{ STB0899_GPIO03CFG,		0x82 },
1077 	{ STB0899_GPIO04CFG,		0x82 },
1078 	{ STB0899_GPIO05CFG,		0x82 },
1079 	{ STB0899_GPIO06CFG,		0x82 },
1080 	{ STB0899_GPIO07CFG,		0x82 },
1081 	{ STB0899_GPIO08CFG,		0x82 },
1082 	{ STB0899_GPIO09CFG,		0x82 },
1083 	{ STB0899_GPIO10CFG,		0x82 },
1084 	{ STB0899_GPIO11CFG,		0x82 },
1085 	{ STB0899_GPIO12CFG,		0x82 },
1086 	{ STB0899_GPIO13CFG,		0x82 },
1087 	{ STB0899_GPIO14CFG,		0x82 },
1088 	{ STB0899_GPIO15CFG,		0x82 },
1089 	{ STB0899_GPIO16CFG,		0x82 },
1090 	{ STB0899_GPIO17CFG,		0x82 },
1091 	{ STB0899_GPIO18CFG,		0x82 },
1092 	{ STB0899_GPIO19CFG,		0x82 },
1093 	{ STB0899_GPIO20CFG,		0x82 },
1094 	{ STB0899_SDATCFG,		0xb8 },
1095 	{ STB0899_SCLTCFG,		0xba },
1096 	{ STB0899_AGCRFCFG,		0x1c }, /* 0x11 */
1097 	{ STB0899_GPIO22,		0x82 }, /* AGCBB2CFG */
1098 	{ STB0899_GPIO21,		0x91 }, /* AGCBB1CFG */
1099 	{ STB0899_DIRCLKCFG,		0x82 },
1100 	{ STB0899_CLKOUT27CFG,		0x7e },
1101 	{ STB0899_STDBYCFG,		0x82 },
1102 	{ STB0899_CS0CFG,		0x82 },
1103 	{ STB0899_CS1CFG,		0x82 },
1104 	{ STB0899_DISEQCOCFG,		0x20 },
1105 	{ STB0899_GPIO32CFG,		0x82 },
1106 	{ STB0899_GPIO33CFG,		0x82 },
1107 	{ STB0899_GPIO34CFG,		0x82 },
1108 	{ STB0899_GPIO35CFG,		0x82 },
1109 	{ STB0899_GPIO36CFG,		0x82 },
1110 	{ STB0899_GPIO37CFG,		0x82 },
1111 	{ STB0899_GPIO38CFG,		0x82 },
1112 	{ STB0899_GPIO39CFG,		0x82 },
1113 	{ STB0899_NCOARSE,		0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
1114 	{ STB0899_SYNTCTRL,		0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
1115 	{ STB0899_FILTCTRL,		0x00 },
1116 	{ STB0899_SYSCTRL,		0x00 },
1117 	{ STB0899_STOPCLK1,		0x20 },
1118 	{ STB0899_STOPCLK2,		0x00 },
1119 	{ STB0899_INTBUFSTATUS,		0x00 },
1120 	{ STB0899_INTBUFCTRL,		0x0a },
1121 	{ 0xffff,			0xff },
1122 };
1123 
1124 static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
1125 	{ STB0899_DEMOD,		0x00 },
1126 	{ STB0899_RCOMPC,		0xc9 },
1127 	{ STB0899_AGC1CN,		0x41 },
1128 	{ STB0899_AGC1REF,		0x10 },
1129 	{ STB0899_RTC,			0x7a },
1130 	{ STB0899_TMGCFG,		0x4e },
1131 	{ STB0899_AGC2REF,		0x34 },
1132 	{ STB0899_TLSR,			0x84 },
1133 	{ STB0899_CFD,			0xc7 },
1134 	{ STB0899_ACLC,			0x87 },
1135 	{ STB0899_BCLC,			0x94 },
1136 	{ STB0899_EQON,			0x41 },
1137 	{ STB0899_LDT,			0xdd },
1138 	{ STB0899_LDT2,			0xc9 },
1139 	{ STB0899_EQUALREF,		0xb4 },
1140 	{ STB0899_TMGRAMP,		0x10 },
1141 	{ STB0899_TMGTHD,		0x30 },
1142 	{ STB0899_IDCCOMP,		0xfb },
1143 	{ STB0899_QDCCOMP,		0x03 },
1144 	{ STB0899_POWERI,		0x3b },
1145 	{ STB0899_POWERQ,		0x3d },
1146 	{ STB0899_RCOMP,		0x81 },
1147 	{ STB0899_AGCIQIN,		0x80 },
1148 	{ STB0899_AGC2I1,		0x04 },
1149 	{ STB0899_AGC2I2,		0xf5 },
1150 	{ STB0899_TLIR,			0x25 },
1151 	{ STB0899_RTF,			0x80 },
1152 	{ STB0899_DSTATUS,		0x00 },
1153 	{ STB0899_LDI,			0xca },
1154 	{ STB0899_CFRM,			0xf1 },
1155 	{ STB0899_CFRL,			0xf3 },
1156 	{ STB0899_NIRM,			0x2a },
1157 	{ STB0899_NIRL,			0x05 },
1158 	{ STB0899_ISYMB,		0x17 },
1159 	{ STB0899_QSYMB,		0xfa },
1160 	{ STB0899_SFRH,			0x2f },
1161 	{ STB0899_SFRM,			0x68 },
1162 	{ STB0899_SFRL,			0x40 },
1163 	{ STB0899_SFRUPH,		0x2f },
1164 	{ STB0899_SFRUPM,		0x68 },
1165 	{ STB0899_SFRUPL,		0x40 },
1166 	{ STB0899_EQUAI1,		0xfd },
1167 	{ STB0899_EQUAQ1,		0x04 },
1168 	{ STB0899_EQUAI2,		0x0f },
1169 	{ STB0899_EQUAQ2,		0xff },
1170 	{ STB0899_EQUAI3,		0xdf },
1171 	{ STB0899_EQUAQ3,		0xfa },
1172 	{ STB0899_EQUAI4,		0x37 },
1173 	{ STB0899_EQUAQ4,		0x0d },
1174 	{ STB0899_EQUAI5,		0xbd },
1175 	{ STB0899_EQUAQ5,		0xf7 },
1176 	{ STB0899_DSTATUS2,		0x00 },
1177 	{ STB0899_VSTATUS,		0x00 },
1178 	{ STB0899_VERROR,		0xff },
1179 	{ STB0899_IQSWAP,		0x2a },
1180 	{ STB0899_ECNT1M,		0x00 },
1181 	{ STB0899_ECNT1L,		0x00 },
1182 	{ STB0899_ECNT2M,		0x00 },
1183 	{ STB0899_ECNT2L,		0x00 },
1184 	{ STB0899_ECNT3M,		0x00 },
1185 	{ STB0899_ECNT3L,		0x00 },
1186 	{ STB0899_FECAUTO1,		0x06 },
1187 	{ STB0899_FECM,			0x01 },
1188 	{ STB0899_VTH12,		0xf0 },
1189 	{ STB0899_VTH23,		0xa0 },
1190 	{ STB0899_VTH34,		0x78 },
1191 	{ STB0899_VTH56,		0x4e },
1192 	{ STB0899_VTH67,		0x48 },
1193 	{ STB0899_VTH78,		0x38 },
1194 	{ STB0899_PRVIT,		0xff },
1195 	{ STB0899_VITSYNC,		0x19 },
1196 	{ STB0899_RSULC,		0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1197 	{ STB0899_TSULC,		0x42 },
1198 	{ STB0899_RSLLC,		0x40 },
1199 	{ STB0899_TSLPL,		0x12 },
1200 	{ STB0899_TSCFGH,		0x0c },
1201 	{ STB0899_TSCFGM,		0x00 },
1202 	{ STB0899_TSCFGL,		0x0c },
1203 	{ STB0899_TSOUT,		0x4d }, /* 0x0d for CAM */
1204 	{ STB0899_RSSYNCDEL,		0x00 },
1205 	{ STB0899_TSINHDELH,		0x02 },
1206 	{ STB0899_TSINHDELM,		0x00 },
1207 	{ STB0899_TSINHDELL,		0x00 },
1208 	{ STB0899_TSLLSTKM,		0x00 },
1209 	{ STB0899_TSLLSTKL,		0x00 },
1210 	{ STB0899_TSULSTKM,		0x00 },
1211 	{ STB0899_TSULSTKL,		0xab },
1212 	{ STB0899_PCKLENUL,		0x00 },
1213 	{ STB0899_PCKLENLL,		0xcc },
1214 	{ STB0899_RSPCKLEN,		0xcc },
1215 	{ STB0899_TSSTATUS,		0x80 },
1216 	{ STB0899_ERRCTRL1,		0xb6 },
1217 	{ STB0899_ERRCTRL2,		0x96 },
1218 	{ STB0899_ERRCTRL3,		0x89 },
1219 	{ STB0899_DMONMSK1,		0x27 },
1220 	{ STB0899_DMONMSK0,		0x03 },
1221 	{ STB0899_DEMAPVIT,		0x5c },
1222 	{ STB0899_PLPARM,		0x1f },
1223 	{ STB0899_PDELCTRL,		0x48 },
1224 	{ STB0899_PDELCTRL2,		0x00 },
1225 	{ STB0899_BBHCTRL1,		0x00 },
1226 	{ STB0899_BBHCTRL2,		0x00 },
1227 	{ STB0899_HYSTTHRESH,		0x77 },
1228 	{ STB0899_MATCSTM,		0x00 },
1229 	{ STB0899_MATCSTL,		0x00 },
1230 	{ STB0899_UPLCSTM,		0x00 },
1231 	{ STB0899_UPLCSTL,		0x00 },
1232 	{ STB0899_DFLCSTM,		0x00 },
1233 	{ STB0899_DFLCSTL,		0x00 },
1234 	{ STB0899_SYNCCST,		0x00 },
1235 	{ STB0899_SYNCDCSTM,		0x00 },
1236 	{ STB0899_SYNCDCSTL,		0x00 },
1237 	{ STB0899_ISI_ENTRY,		0x00 },
1238 	{ STB0899_ISI_BIT_EN,		0x00 },
1239 	{ STB0899_MATSTRM,		0x00 },
1240 	{ STB0899_MATSTRL,		0x00 },
1241 	{ STB0899_UPLSTRM,		0x00 },
1242 	{ STB0899_UPLSTRL,		0x00 },
1243 	{ STB0899_DFLSTRM,		0x00 },
1244 	{ STB0899_DFLSTRL,		0x00 },
1245 	{ STB0899_SYNCSTR,		0x00 },
1246 	{ STB0899_SYNCDSTRM,		0x00 },
1247 	{ STB0899_SYNCDSTRL,		0x00 },
1248 	{ STB0899_CFGPDELSTATUS1,	0x10 },
1249 	{ STB0899_CFGPDELSTATUS2,	0x00 },
1250 	{ STB0899_BBFERRORM,		0x00 },
1251 	{ STB0899_BBFERRORL,		0x00 },
1252 	{ STB0899_UPKTERRORM,		0x00 },
1253 	{ STB0899_UPKTERRORL,		0x00 },
1254 	{ 0xffff,			0xff },
1255 };
1256 
1257 static struct stb0899_config tt3200_config = {
1258 	.init_dev		= tt3200_stb0899_s1_init_1,
1259 	.init_s2_demod		= stb0899_s2_init_2,
1260 	.init_s1_demod		= tt3200_stb0899_s1_init_3,
1261 	.init_s2_fec		= stb0899_s2_init_4,
1262 	.init_tst		= stb0899_s1_init_5,
1263 
1264 	.postproc		= NULL,
1265 
1266 	.demod_address		= 0x68,
1267 
1268 	.xtal_freq		= 27000000,
1269 	.inversion		= IQ_SWAP_ON,
1270 
1271 	.lo_clk			= 76500000,
1272 	.hi_clk			= 99000000,
1273 
1274 	.esno_ave		= STB0899_DVBS2_ESNO_AVE,
1275 	.esno_quant		= STB0899_DVBS2_ESNO_QUANT,
1276 	.avframes_coarse	= STB0899_DVBS2_AVFRAMES_COARSE,
1277 	.avframes_fine		= STB0899_DVBS2_AVFRAMES_FINE,
1278 	.miss_threshold		= STB0899_DVBS2_MISS_THRESHOLD,
1279 	.uwp_threshold_acq	= STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1280 	.uwp_threshold_track	= STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1281 	.uwp_threshold_sof	= STB0899_DVBS2_UWP_THRESHOLD_SOF,
1282 	.sof_search_timeout	= STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1283 
1284 	.btr_nco_bits		= STB0899_DVBS2_BTR_NCO_BITS,
1285 	.btr_gain_shift_offset	= STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1286 	.crl_nco_bits		= STB0899_DVBS2_CRL_NCO_BITS,
1287 	.ldpc_max_iter		= STB0899_DVBS2_LDPC_MAX_ITER,
1288 
1289 	.tuner_get_frequency	= stb6100_get_frequency,
1290 	.tuner_set_frequency	= stb6100_set_frequency,
1291 	.tuner_set_bandwidth	= stb6100_set_bandwidth,
1292 	.tuner_get_bandwidth	= stb6100_get_bandwidth,
1293 	.tuner_set_rfsiggain	= NULL
1294 };
1295 
1296 static struct stb6100_config tt3200_stb6100_config = {
1297 	.tuner_address	= 0x60,
1298 	.refclock	= 27000000,
1299 };
1300 
1301 static void frontend_init(struct budget_ci *budget_ci)
1302 {
1303 	switch (budget_ci->budget.dev->pci->subsystem_device) {
1304 	case 0x100c:		// Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
1305 		budget_ci->budget.dvb_frontend =
1306 			dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
1307 		if (budget_ci->budget.dvb_frontend) {
1308 			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
1309 			budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1310 			break;
1311 		}
1312 		break;
1313 
1314 	case 0x100f:		// Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
1315 		budget_ci->budget.dvb_frontend =
1316 			dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
1317 		if (budget_ci->budget.dvb_frontend) {
1318 			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
1319 			break;
1320 		}
1321 		break;
1322 
1323 	case 0x1010:		// TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
1324 		budget_ci->tuner_pll_address = 0x61;
1325 		budget_ci->budget.dvb_frontend =
1326 			dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1327 		if (budget_ci->budget.dvb_frontend) {
1328 			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1329 			break;
1330 		}
1331 		break;
1332 
1333 	case 0x1011:		// Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
1334 		budget_ci->tuner_pll_address = 0x63;
1335 		budget_ci->budget.dvb_frontend =
1336 			dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1337 		if (budget_ci->budget.dvb_frontend) {
1338 			budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1339 			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1340 			break;
1341 		}
1342 		break;
1343 
1344 	case 0x1012:		// TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
1345 		budget_ci->tuner_pll_address = 0x60;
1346 		budget_ci->budget.dvb_frontend =
1347 			dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
1348 		if (budget_ci->budget.dvb_frontend) {
1349 			budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1350 			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1351 			break;
1352 		}
1353 		break;
1354 
1355 	case 0x1017:		// TT S-1500 PCI
1356 		budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
1357 		if (budget_ci->budget.dvb_frontend) {
1358 			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
1359 			budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1360 
1361 			budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
1362 			if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
1363 				pr_err("%s(): No LNBP21 found!\n", __func__);
1364 				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1365 				budget_ci->budget.dvb_frontend = NULL;
1366 			}
1367 		}
1368 		break;
1369 
1370 	case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
1371 		budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
1372 		if (budget_ci->budget.dvb_frontend) {
1373 			if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
1374 				pr_err("%s(): No tda827x found!\n", __func__);
1375 				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1376 				budget_ci->budget.dvb_frontend = NULL;
1377 			}
1378 		}
1379 		break;
1380 
1381 	case 0x101b: /* TT S-1500B (BSBE1-D01A - STV0288/STB6000/LNBP21) */
1382 		budget_ci->budget.dvb_frontend = dvb_attach(stv0288_attach, &stv0288_bsbe1_d01a_config, &budget_ci->budget.i2c_adap);
1383 		if (budget_ci->budget.dvb_frontend) {
1384 			if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) {
1385 				if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1386 					pr_err("%s(): No LNBP21 found!\n", __func__);
1387 					dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1388 					budget_ci->budget.dvb_frontend = NULL;
1389 				}
1390 			} else {
1391 				pr_err("%s(): No STB6000 found!\n", __func__);
1392 				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1393 				budget_ci->budget.dvb_frontend = NULL;
1394 			}
1395 		}
1396 		break;
1397 
1398 	case 0x1019:		// TT S2-3200 PCI
1399 		/*
1400 		 * NOTE! on some STB0899 versions, the internal PLL takes a longer time
1401 		 * to settle, aka LOCK. On the older revisions of the chip, we don't see
1402 		 * this, as a result on the newer chips the entire clock tree, will not
1403 		 * be stable after a freshly POWER 'ed up situation.
1404 		 * In this case, we should RESET the STB0899 (Active LOW) and wait for
1405 		 * PLL stabilization.
1406 		 *
1407 		 * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is
1408 		 * connected to the SAA7146 GPIO, GPIO2, Pin 142
1409 		 */
1410 		/* Reset Demodulator */
1411 		saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
1412 		/* Wait for everything to die */
1413 		msleep(50);
1414 		/* Pull it up out of Reset state */
1415 		saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
1416 		/* Wait for PLL to stabilize */
1417 		msleep(250);
1418 		/*
1419 		 * PLL state should be stable now. Ideally, we should check
1420 		 * for PLL LOCK status. But well, never mind!
1421 		 */
1422 		budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
1423 		if (budget_ci->budget.dvb_frontend) {
1424 			if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
1425 				if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1426 					pr_err("%s(): No LNBP21 found!\n", __func__);
1427 					dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1428 					budget_ci->budget.dvb_frontend = NULL;
1429 				}
1430 			} else {
1431 				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1432 				budget_ci->budget.dvb_frontend = NULL;
1433 			}
1434 		}
1435 		break;
1436 
1437 	}
1438 
1439 	if (budget_ci->budget.dvb_frontend == NULL) {
1440 		pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1441 		       budget_ci->budget.dev->pci->vendor,
1442 		       budget_ci->budget.dev->pci->device,
1443 		       budget_ci->budget.dev->pci->subsystem_vendor,
1444 		       budget_ci->budget.dev->pci->subsystem_device);
1445 	} else {
1446 		if (dvb_register_frontend
1447 		    (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
1448 			pr_err("Frontend registration failed!\n");
1449 			dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1450 			budget_ci->budget.dvb_frontend = NULL;
1451 		}
1452 	}
1453 }
1454 
1455 static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1456 {
1457 	struct budget_ci *budget_ci;
1458 	int err;
1459 
1460 	budget_ci = kzalloc_obj(struct budget_ci);
1461 	if (!budget_ci) {
1462 		err = -ENOMEM;
1463 		goto out1;
1464 	}
1465 
1466 	dprintk(2, "budget_ci: %p\n", budget_ci);
1467 
1468 	dev->ext_priv = budget_ci;
1469 
1470 	err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
1471 				adapter_nr);
1472 	if (err)
1473 		goto out2;
1474 
1475 	err = msp430_ir_init(budget_ci);
1476 	if (err)
1477 		goto out3;
1478 
1479 	ciintf_init(budget_ci);
1480 
1481 	budget_ci->budget.dvb_adapter.priv = budget_ci;
1482 	frontend_init(budget_ci);
1483 
1484 	ttpci_budget_init_hooks(&budget_ci->budget);
1485 
1486 	return 0;
1487 
1488 out3:
1489 	ttpci_budget_deinit(&budget_ci->budget);
1490 out2:
1491 	kfree(budget_ci);
1492 out1:
1493 	return err;
1494 }
1495 
1496 static int budget_ci_detach(struct saa7146_dev *dev)
1497 {
1498 	struct budget_ci *budget_ci = dev->ext_priv;
1499 	struct saa7146_dev *saa = budget_ci->budget.dev;
1500 	int err;
1501 
1502 	if (budget_ci->budget.ci_present)
1503 		ciintf_deinit(budget_ci);
1504 	msp430_ir_deinit(budget_ci);
1505 	if (budget_ci->budget.dvb_frontend) {
1506 		dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
1507 		dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1508 	}
1509 	err = ttpci_budget_deinit(&budget_ci->budget);
1510 
1511 	// disable frontend and CI interface
1512 	saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1513 
1514 	kfree(budget_ci);
1515 
1516 	return err;
1517 }
1518 
1519 static struct saa7146_extension budget_extension;
1520 
1521 MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
1522 MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1523 MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T	 PCI", BUDGET_TT);
1524 MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1525 MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1526 MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1527 MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1528 MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT);
1529 
1530 static const struct pci_device_id pci_tbl[] = {
1531 	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
1532 	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
1533 	MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
1534 	MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
1535 	MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
1536 	MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1537 	MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1538 	MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1539 	MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b),
1540 	{
1541 	 .vendor = 0,
1542 	}
1543 };
1544 
1545 MODULE_DEVICE_TABLE(pci, pci_tbl);
1546 
1547 static struct saa7146_extension budget_extension = {
1548 	.name = "budget_ci dvb",
1549 	.flags = SAA7146_USE_I2C_IRQ,
1550 
1551 	.module = THIS_MODULE,
1552 	.pci_tbl = &pci_tbl[0],
1553 	.attach = budget_ci_attach,
1554 	.detach = budget_ci_detach,
1555 
1556 	.irq_mask = MASK_03 | MASK_06 | MASK_10,
1557 	.irq_func = budget_ci_irq,
1558 };
1559 
1560 static int __init budget_ci_init(void)
1561 {
1562 	return saa7146_register_extension(&budget_extension);
1563 }
1564 
1565 static void __exit budget_ci_exit(void)
1566 {
1567 	saa7146_unregister_extension(&budget_extension);
1568 }
1569 
1570 module_init(budget_ci_init);
1571 module_exit(budget_ci_exit);
1572 
1573 MODULE_LICENSE("GPL");
1574 MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1575 MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards w/ CI-module produced by Siemens, Technotrend, Hauppauge");
1576