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