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