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