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