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