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