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