Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee13...
[linux-2.6] / drivers / media / dvb / ttpci / budget-av.c
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/dvb/
34  */
35
36 #include "budget.h"
37 #include "stv0299.h"
38 #include "tda10021.h"
39 #include "tda1004x.h"
40 #include "tua6100.h"
41 #include "dvb-pll.h"
42 #include <media/saa7146_vv.h>
43 #include <linux/module.h>
44 #include <linux/errno.h>
45 #include <linux/slab.h>
46 #include <linux/interrupt.h>
47 #include <linux/input.h>
48 #include <linux/spinlock.h>
49
50 #include "dvb_ca_en50221.h"
51
52 #define DEBICICAM               0x02420000
53
54 #define SLOTSTATUS_NONE         1
55 #define SLOTSTATUS_PRESENT      2
56 #define SLOTSTATUS_RESET        4
57 #define SLOTSTATUS_READY        8
58 #define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
59
60 struct budget_av {
61         struct budget budget;
62         struct video_device *vd;
63         int cur_input;
64         int has_saa7113;
65         struct tasklet_struct ciintf_irq_tasklet;
66         int slot_status;
67         struct dvb_ca_en50221 ca;
68         u8 reinitialise_demod:1;
69         u8 tda10021_poclkp:1;
70         u8 tda10021_ts_enabled;
71         int (*tda10021_set_frontend)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
72 };
73
74 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
75
76
77 /* GPIO Connections:
78  * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
79  * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
80  * 2 - CI Card Enable (Active Low)
81  * 3 - CI Card Detect
82  */
83
84 /****************************************************************************
85  * INITIALIZATION
86  ****************************************************************************/
87
88 static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
89 {
90         u8 mm1[] = { 0x00 };
91         u8 mm2[] = { 0x00 };
92         struct i2c_msg msgs[2];
93
94         msgs[0].flags = 0;
95         msgs[1].flags = I2C_M_RD;
96         msgs[0].addr = msgs[1].addr = id / 2;
97         mm1[0] = reg;
98         msgs[0].len = 1;
99         msgs[1].len = 1;
100         msgs[0].buf = mm1;
101         msgs[1].buf = mm2;
102
103         i2c_transfer(i2c, msgs, 2);
104
105         return mm2[0];
106 }
107
108 static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
109 {
110         u8 mm1[] = { reg };
111         struct i2c_msg msgs[2] = {
112                 {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
113                 {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
114         };
115
116         if (i2c_transfer(i2c, msgs, 2) != 2)
117                 return -EIO;
118
119         return 0;
120 }
121
122 static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
123 {
124         u8 msg[2] = { reg, val };
125         struct i2c_msg msgs;
126
127         msgs.flags = 0;
128         msgs.addr = id / 2;
129         msgs.len = 2;
130         msgs.buf = msg;
131         return i2c_transfer(i2c, &msgs, 1);
132 }
133
134 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
135 {
136         struct budget_av *budget_av = (struct budget_av *) ca->data;
137         int result;
138
139         if (slot != 0)
140                 return -EINVAL;
141
142         saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
143         udelay(1);
144
145         result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
146         if (result == -ETIMEDOUT) {
147                 ciintf_slot_shutdown(ca, slot);
148                 printk(KERN_INFO "budget-av: cam ejected 1\n");
149         }
150         return result;
151 }
152
153 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
154 {
155         struct budget_av *budget_av = (struct budget_av *) ca->data;
156         int result;
157
158         if (slot != 0)
159                 return -EINVAL;
160
161         saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
162         udelay(1);
163
164         result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
165         if (result == -ETIMEDOUT) {
166                 ciintf_slot_shutdown(ca, slot);
167                 printk(KERN_INFO "budget-av: cam ejected 2\n");
168         }
169         return result;
170 }
171
172 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
173 {
174         struct budget_av *budget_av = (struct budget_av *) ca->data;
175         int result;
176
177         if (slot != 0)
178                 return -EINVAL;
179
180         saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
181         udelay(1);
182
183         result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
184         if ((result == -ETIMEDOUT) || ((result == 0xff) && ((address & 3) < 2))) {
185                 ciintf_slot_shutdown(ca, slot);
186                 printk(KERN_INFO "budget-av: cam ejected 3\n");
187                 return -ETIMEDOUT;
188         }
189         return result;
190 }
191
192 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
193 {
194         struct budget_av *budget_av = (struct budget_av *) ca->data;
195         int result;
196
197         if (slot != 0)
198                 return -EINVAL;
199
200         saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
201         udelay(1);
202
203         result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
204         if (result == -ETIMEDOUT) {
205                 ciintf_slot_shutdown(ca, slot);
206                 printk(KERN_INFO "budget-av: cam ejected 5\n");
207         }
208         return result;
209 }
210
211 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
212 {
213         struct budget_av *budget_av = (struct budget_av *) ca->data;
214         struct saa7146_dev *saa = budget_av->budget.dev;
215
216         if (slot != 0)
217                 return -EINVAL;
218
219         dprintk(1, "ciintf_slot_reset\n");
220         budget_av->slot_status = SLOTSTATUS_RESET;
221
222         saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
223
224         saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
225         msleep(2);
226         saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
227         msleep(20); /* 20 ms Vcc settling time */
228
229         saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
230         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
231         msleep(20);
232
233         /* reinitialise the frontend if necessary */
234         if (budget_av->reinitialise_demod)
235                 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
236
237         /* set tda10021 back to original clock configuration on reset */
238         if (budget_av->tda10021_poclkp) {
239                 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
240                 budget_av->tda10021_ts_enabled = 0;
241         }
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         /* set tda10021 back to original clock configuration when cam removed */
260         if (budget_av->tda10021_poclkp) {
261                 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
262                 budget_av->tda10021_ts_enabled = 0;
263         }
264         return 0;
265 }
266
267 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
268 {
269         struct budget_av *budget_av = (struct budget_av *) ca->data;
270         struct saa7146_dev *saa = budget_av->budget.dev;
271
272         if (slot != 0)
273                 return -EINVAL;
274
275         dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
276
277         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
278
279         /* tda10021 seems to need a different TS clock config when data is routed to the CAM */
280         if (budget_av->tda10021_poclkp) {
281                 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
282                 budget_av->tda10021_ts_enabled = 1;
283         }
284
285         return 0;
286 }
287
288 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
289 {
290         struct budget_av *budget_av = (struct budget_av *) ca->data;
291         struct saa7146_dev *saa = budget_av->budget.dev;
292         int result;
293
294         if (slot != 0)
295                 return -EINVAL;
296
297         /* test the card detect line - needs to be done carefully
298          * since it never goes high for some CAMs on this interface (e.g. topuptv) */
299         if (budget_av->slot_status == SLOTSTATUS_NONE) {
300                 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
301                 udelay(1);
302                 if (saa7146_read(saa, PSR) & MASK_06) {
303                         if (budget_av->slot_status == SLOTSTATUS_NONE) {
304                                 budget_av->slot_status = SLOTSTATUS_PRESENT;
305                                 printk(KERN_INFO "budget-av: cam inserted A\n");
306                         }
307                 }
308                 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
309         }
310
311         /* We also try and read from IO memory to work round the above detection bug. If
312          * there is no CAM, we will get a timeout. Only done if there is no cam
313          * present, since this test actually breaks some cams :(
314          *
315          * if the CI interface is not open, we also do the above test since we
316          * don't care if the cam has problems - we'll be resetting it on open() anyway */
317         if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
318                 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
319                 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
320                 if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
321                         budget_av->slot_status = SLOTSTATUS_PRESENT;
322                         printk(KERN_INFO "budget-av: cam inserted B\n");
323                 } else if (result < 0) {
324                         if (budget_av->slot_status != SLOTSTATUS_NONE) {
325                                 ciintf_slot_shutdown(ca, slot);
326                                 printk(KERN_INFO "budget-av: cam ejected 5\n");
327                                 return 0;
328                         }
329                 }
330         }
331
332         /* read from attribute memory in reset/ready state to know when the CAM is ready */
333         if (budget_av->slot_status == SLOTSTATUS_RESET) {
334                 result = ciintf_read_attribute_mem(ca, slot, 0);
335                 if (result == 0x1d) {
336                         budget_av->slot_status = SLOTSTATUS_READY;
337                 }
338         }
339
340         /* work out correct return code */
341         if (budget_av->slot_status != SLOTSTATUS_NONE) {
342                 if (budget_av->slot_status & SLOTSTATUS_READY) {
343                         return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
344                 }
345                 return DVB_CA_EN50221_POLL_CAM_PRESENT;
346         }
347         return 0;
348 }
349
350 static int ciintf_init(struct budget_av *budget_av)
351 {
352         struct saa7146_dev *saa = budget_av->budget.dev;
353         int result;
354
355         memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
356
357         saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
358         saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
359         saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
360         saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
361
362         /* Enable DEBI pins */
363         saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
364
365         /* register CI interface */
366         budget_av->ca.owner = THIS_MODULE;
367         budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
368         budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
369         budget_av->ca.read_cam_control = ciintf_read_cam_control;
370         budget_av->ca.write_cam_control = ciintf_write_cam_control;
371         budget_av->ca.slot_reset = ciintf_slot_reset;
372         budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
373         budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
374         budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
375         budget_av->ca.data = budget_av;
376         budget_av->budget.ci_present = 1;
377         budget_av->slot_status = SLOTSTATUS_NONE;
378
379         if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
380                                           &budget_av->ca, 0, 1)) != 0) {
381                 printk(KERN_ERR "budget-av: ci initialisation failed.\n");
382                 goto error;
383         }
384
385         printk(KERN_INFO "budget-av: ci interface initialised.\n");
386         return 0;
387
388 error:
389         saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
390         return result;
391 }
392
393 static void ciintf_deinit(struct budget_av *budget_av)
394 {
395         struct saa7146_dev *saa = budget_av->budget.dev;
396
397         saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
398         saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
399         saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
400         saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
401
402         /* release the CA device */
403         dvb_ca_en50221_release(&budget_av->ca);
404
405         /* disable DEBI pins */
406         saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
407 }
408
409
410 static const u8 saa7113_tab[] = {
411         0x01, 0x08,
412         0x02, 0xc0,
413         0x03, 0x33,
414         0x04, 0x00,
415         0x05, 0x00,
416         0x06, 0xeb,
417         0x07, 0xe0,
418         0x08, 0x28,
419         0x09, 0x00,
420         0x0a, 0x80,
421         0x0b, 0x47,
422         0x0c, 0x40,
423         0x0d, 0x00,
424         0x0e, 0x01,
425         0x0f, 0x44,
426
427         0x10, 0x08,
428         0x11, 0x0c,
429         0x12, 0x7b,
430         0x13, 0x00,
431         0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
432
433         0x57, 0xff,
434         0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
435         0x5b, 0x83, 0x5e, 0x00,
436         0xff
437 };
438
439 static int saa7113_init(struct budget_av *budget_av)
440 {
441         struct budget *budget = &budget_av->budget;
442         struct saa7146_dev *saa = budget->dev;
443         const u8 *data = saa7113_tab;
444
445         saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
446         msleep(200);
447
448         if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
449                 dprintk(1, "saa7113 not found on KNC card\n");
450                 return -ENODEV;
451         }
452
453         dprintk(1, "saa7113 detected and initializing\n");
454
455         while (*data != 0xff) {
456                 i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
457                 data += 2;
458         }
459
460         dprintk(1, "saa7113  status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
461
462         return 0;
463 }
464
465 static int saa7113_setinput(struct budget_av *budget_av, int input)
466 {
467         struct budget *budget = &budget_av->budget;
468
469         if (1 != budget_av->has_saa7113)
470                 return -ENODEV;
471
472         if (input == 1) {
473                 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
474                 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
475         } else if (input == 0) {
476                 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
477                 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
478         } else
479                 return -EINVAL;
480
481         budget_av->cur_input = input;
482         return 0;
483 }
484
485
486 static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
487 {
488         u8 aclk = 0;
489         u8 bclk = 0;
490         u8 m1;
491
492         aclk = 0xb5;
493         if (srate < 2000000)
494                 bclk = 0x86;
495         else if (srate < 5000000)
496                 bclk = 0x89;
497         else if (srate < 15000000)
498                 bclk = 0x8f;
499         else if (srate < 45000000)
500                 bclk = 0x95;
501
502         m1 = 0x14;
503         if (srate < 4000000)
504                 m1 = 0x10;
505
506         stv0299_writereg(fe, 0x13, aclk);
507         stv0299_writereg(fe, 0x14, bclk);
508         stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
509         stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
510         stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
511         stv0299_writereg(fe, 0x0f, 0x80 | m1);
512
513         return 0;
514 }
515
516 static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe,
517                                                  struct dvb_frontend_parameters *params)
518 {
519         u32 div;
520         u8 buf[4];
521         struct budget *budget = (struct budget *) fe->dvb->priv;
522         struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
523
524         if ((params->frequency < 950000) || (params->frequency > 2150000))
525                 return -EINVAL;
526
527         div = (params->frequency + (125 - 1)) / 125;    // round correctly
528         buf[0] = (div >> 8) & 0x7f;
529         buf[1] = div & 0xff;
530         buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
531         buf[3] = 0x20;
532
533         if (params->u.qpsk.symbol_rate < 4000000)
534                 buf[3] |= 1;
535
536         if (params->frequency < 1250000)
537                 buf[3] |= 0;
538         else if (params->frequency < 1550000)
539                 buf[3] |= 0x40;
540         else if (params->frequency < 2050000)
541                 buf[3] |= 0x80;
542         else if (params->frequency < 2150000)
543                 buf[3] |= 0xC0;
544
545         if (fe->ops.i2c_gate_ctrl)
546                 fe->ops.i2c_gate_ctrl(fe, 1);
547         if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
548                 return -EIO;
549         return 0;
550 }
551
552 static u8 typhoon_cinergy1200s_inittab[] = {
553         0x01, 0x15,
554         0x02, 0x30,
555         0x03, 0x00,
556         0x04, 0x7d,             /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
557         0x05, 0x35,             /* I2CT = 0, SCLT = 1, SDAT = 1 */
558         0x06, 0x40,             /* DAC not used, set to high impendance mode */
559         0x07, 0x00,             /* DAC LSB */
560         0x08, 0x40,             /* DiSEqC off */
561         0x09, 0x00,             /* FIFO */
562         0x0c, 0x51,             /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
563         0x0d, 0x82,             /* DC offset compensation = ON, beta_agc1 = 2 */
564         0x0e, 0x23,             /* alpha_tmg = 2, beta_tmg = 3 */
565         0x10, 0x3f,             // AGC2  0x3d
566         0x11, 0x84,
567         0x12, 0xb9,
568         0x15, 0xc9,             // lock detector threshold
569         0x16, 0x00,
570         0x17, 0x00,
571         0x18, 0x00,
572         0x19, 0x00,
573         0x1a, 0x00,
574         0x1f, 0x50,
575         0x20, 0x00,
576         0x21, 0x00,
577         0x22, 0x00,
578         0x23, 0x00,
579         0x28, 0x00,             // out imp: normal  out type: parallel FEC mode:0
580         0x29, 0x1e,             // 1/2 threshold
581         0x2a, 0x14,             // 2/3 threshold
582         0x2b, 0x0f,             // 3/4 threshold
583         0x2c, 0x09,             // 5/6 threshold
584         0x2d, 0x05,             // 7/8 threshold
585         0x2e, 0x01,
586         0x31, 0x1f,             // test all FECs
587         0x32, 0x19,             // viterbi and synchro search
588         0x33, 0xfc,             // rs control
589         0x34, 0x93,             // error control
590         0x0f, 0x92,
591         0xff, 0xff
592 };
593
594 static struct stv0299_config typhoon_config = {
595         .demod_address = 0x68,
596         .inittab = typhoon_cinergy1200s_inittab,
597         .mclk = 88000000UL,
598         .invert = 0,
599         .skip_reinit = 0,
600         .lock_output = STV0229_LOCKOUTPUT_1,
601         .volt13_op0_op1 = STV0299_VOLT13_OP0,
602         .min_delay_ms = 100,
603         .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
604 };
605
606
607 static struct stv0299_config cinergy_1200s_config = {
608         .demod_address = 0x68,
609         .inittab = typhoon_cinergy1200s_inittab,
610         .mclk = 88000000UL,
611         .invert = 0,
612         .skip_reinit = 0,
613         .lock_output = STV0229_LOCKOUTPUT_0,
614         .volt13_op0_op1 = STV0299_VOLT13_OP0,
615         .min_delay_ms = 100,
616         .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
617 };
618
619 static struct stv0299_config cinergy_1200s_1894_0010_config = {
620         .demod_address = 0x68,
621         .inittab = typhoon_cinergy1200s_inittab,
622         .mclk = 88000000UL,
623         .invert = 1,
624         .skip_reinit = 0,
625         .lock_output = STV0229_LOCKOUTPUT_1,
626         .volt13_op0_op1 = STV0299_VOLT13_OP0,
627         .min_delay_ms = 100,
628         .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
629 };
630
631 static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
632 {
633         struct budget *budget = (struct budget *) fe->dvb->priv;
634         u8 buf[4];
635         struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
636
637 #define TUNER_MUL 62500
638
639         u32 div = (params->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
640
641         buf[0] = (div >> 8) & 0x7f;
642         buf[1] = div & 0xff;
643         buf[2] = 0x86;
644         buf[3] = (params->frequency < 150000000 ? 0x01 :
645                   params->frequency < 445000000 ? 0x02 : 0x04);
646
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)
650                 return -EIO;
651         return 0;
652 }
653
654 static struct tda10021_config philips_cu1216_config = {
655         .demod_address = 0x0c,
656 };
657
658
659
660
661 static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
662 {
663         struct budget *budget = (struct budget *) fe->dvb->priv;
664         static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
665         struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
666
667         // setup PLL configuration
668         if (fe->ops.i2c_gate_ctrl)
669                 fe->ops.i2c_gate_ctrl(fe, 1);
670         if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
671                 return -EIO;
672         msleep(1);
673
674         return 0;
675 }
676
677 static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
678 {
679         struct budget *budget = (struct budget *) fe->dvb->priv;
680         u8 tuner_buf[4];
681         struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
682                         sizeof(tuner_buf) };
683         int tuner_frequency = 0;
684         u8 band, cp, filter;
685
686         // determine charge pump
687         tuner_frequency = params->frequency + 36166000;
688         if (tuner_frequency < 87000000)
689                 return -EINVAL;
690         else if (tuner_frequency < 130000000)
691                 cp = 3;
692         else if (tuner_frequency < 160000000)
693                 cp = 5;
694         else if (tuner_frequency < 200000000)
695                 cp = 6;
696         else if (tuner_frequency < 290000000)
697                 cp = 3;
698         else if (tuner_frequency < 420000000)
699                 cp = 5;
700         else if (tuner_frequency < 480000000)
701                 cp = 6;
702         else if (tuner_frequency < 620000000)
703                 cp = 3;
704         else if (tuner_frequency < 830000000)
705                 cp = 5;
706         else if (tuner_frequency < 895000000)
707                 cp = 7;
708         else
709                 return -EINVAL;
710
711         // determine band
712         if (params->frequency < 49000000)
713                 return -EINVAL;
714         else if (params->frequency < 161000000)
715                 band = 1;
716         else if (params->frequency < 444000000)
717                 band = 2;
718         else if (params->frequency < 861000000)
719                 band = 4;
720         else
721                 return -EINVAL;
722
723         // setup PLL filter
724         switch (params->u.ofdm.bandwidth) {
725         case BANDWIDTH_6_MHZ:
726                 filter = 0;
727                 break;
728
729         case BANDWIDTH_7_MHZ:
730                 filter = 0;
731                 break;
732
733         case BANDWIDTH_8_MHZ:
734                 filter = 1;
735                 break;
736
737         default:
738                 return -EINVAL;
739         }
740
741         // calculate divisor
742         // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
743         tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
744
745         // setup tuner buffer
746         tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
747         tuner_buf[1] = tuner_frequency & 0xff;
748         tuner_buf[2] = 0xca;
749         tuner_buf[3] = (cp << 5) | (filter << 3) | band;
750
751         if (fe->ops.i2c_gate_ctrl)
752                 fe->ops.i2c_gate_ctrl(fe, 1);
753         if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
754                 return -EIO;
755
756         msleep(1);
757         return 0;
758 }
759
760 static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
761                                            const struct firmware **fw, char *name)
762 {
763         struct budget *budget = (struct budget *) fe->dvb->priv;
764
765         return request_firmware(fw, name, &budget->dev->pci->dev);
766 }
767
768 static struct tda1004x_config philips_tu1216_config = {
769
770         .demod_address = 0x8,
771         .invert = 1,
772         .invert_oclk = 1,
773         .xtal_freq = TDA10046_XTAL_4M,
774         .agc_config = TDA10046_AGC_DEFAULT,
775         .if_freq = TDA10046_FREQ_3617,
776         .request_firmware = philips_tu1216_request_firmware,
777 };
778
779 static u8 philips_sd1878_inittab[] = {
780         0x01, 0x15,
781         0x02, 0x30,
782         0x03, 0x00,
783         0x04, 0x7d,
784         0x05, 0x35,
785         0x06, 0x40,
786         0x07, 0x00,
787         0x08, 0x43,
788         0x09, 0x02,
789         0x0C, 0x51,
790         0x0D, 0x82,
791         0x0E, 0x23,
792         0x10, 0x3f,
793         0x11, 0x84,
794         0x12, 0xb9,
795         0x15, 0xc9,
796         0x16, 0x19,
797         0x17, 0x8c,
798         0x18, 0x59,
799         0x19, 0xf8,
800         0x1a, 0xfe,
801         0x1c, 0x7f,
802         0x1d, 0x00,
803         0x1e, 0x00,
804         0x1f, 0x50,
805         0x20, 0x00,
806         0x21, 0x00,
807         0x22, 0x00,
808         0x23, 0x00,
809         0x28, 0x00,
810         0x29, 0x28,
811         0x2a, 0x14,
812         0x2b, 0x0f,
813         0x2c, 0x09,
814         0x2d, 0x09,
815         0x31, 0x1f,
816         0x32, 0x19,
817         0x33, 0xfc,
818         0x34, 0x93,
819         0xff, 0xff
820 };
821
822 static int philips_sd1878_tda8261_tuner_set_params(struct dvb_frontend *fe,
823                                                    struct dvb_frontend_parameters *params)
824 {
825         u8              buf[4];
826         int             rc;
827         struct i2c_msg  tuner_msg = {.addr=0x60,.flags=0,.buf=buf,.len=sizeof(buf)};
828         struct budget *budget = (struct budget *) fe->dvb->priv;
829
830         if((params->frequency < 950000) || (params->frequency > 2150000))
831                 return -EINVAL;
832
833         rc=dvb_pll_configure(&dvb_pll_philips_sd1878_tda8261, buf,
834                         params->frequency, 0);
835         if(rc < 0) return rc;
836
837         if (fe->ops.i2c_gate_ctrl)
838                 fe->ops.i2c_gate_ctrl(fe, 1);
839         if(i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
840                 return -EIO;
841
842     return 0;
843 }
844
845 static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
846                 u32 srate, u32 ratio)
847 {
848         u8 aclk = 0;
849         u8 bclk = 0;
850         u8 m1;
851
852         aclk = 0xb5;
853         if (srate < 2000000)
854                 bclk = 0x86;
855         else if (srate < 5000000)
856                 bclk = 0x89;
857         else if (srate < 15000000)
858                 bclk = 0x8f;
859         else if (srate < 45000000)
860                 bclk = 0x95;
861
862         m1 = 0x14;
863         if (srate < 4000000)
864                 m1 = 0x10;
865
866         stv0299_writereg(fe, 0x0e, 0x23);
867         stv0299_writereg(fe, 0x0f, 0x94);
868         stv0299_writereg(fe, 0x10, 0x39);
869         stv0299_writereg(fe, 0x13, aclk);
870         stv0299_writereg(fe, 0x14, bclk);
871         stv0299_writereg(fe, 0x15, 0xc9);
872         stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
873         stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
874         stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
875         stv0299_writereg(fe, 0x0f, 0x80 | m1);
876
877         return 0;
878 }
879
880 static struct stv0299_config philips_sd1878_config = {
881         .demod_address = 0x68,
882      .inittab = philips_sd1878_inittab,
883         .mclk = 88000000UL,
884         .invert = 0,
885         .skip_reinit = 0,
886         .lock_output = STV0229_LOCKOUTPUT_1,
887         .volt13_op0_op1 = STV0299_VOLT13_OP0,
888         .min_delay_ms = 100,
889         .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
890 };
891
892 static u8 read_pwm(struct budget_av *budget_av)
893 {
894         u8 b = 0xff;
895         u8 pwm;
896         struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
897         {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
898         };
899
900         if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
901             || (pwm == 0xff))
902                 pwm = 0x48;
903
904         return pwm;
905 }
906
907 #define SUBID_DVBS_KNC1         0x0010
908 #define SUBID_DVBS_KNC1_PLUS    0x0011
909 #define SUBID_DVBS_TYPHOON      0x4f56
910 #define SUBID_DVBS_CINERGY1200  0x1154
911 #define SUBID_DVBS_CYNERGY1200N 0x1155
912
913 #define SUBID_DVBS_TV_STAR      0x0014
914 #define SUBID_DVBS_TV_STAR_CI   0x0016
915 #define SUBID_DVBS_EASYWATCH_1  0x001a
916 #define SUBID_DVBS_EASYWATCH    0x001e
917 #define SUBID_DVBC_KNC1         0x0020
918 #define SUBID_DVBC_KNC1_PLUS    0x0021
919 #define SUBID_DVBC_CINERGY1200  0x1156
920
921 #define SUBID_DVBT_KNC1_PLUS    0x0031
922 #define SUBID_DVBT_KNC1         0x0030
923 #define SUBID_DVBT_CINERGY1200  0x1157
924
925
926 static int tda10021_set_frontend(struct dvb_frontend *fe,
927                                  struct dvb_frontend_parameters *p)
928 {
929         struct budget_av* budget_av = fe->dvb->priv;
930         int result;
931
932         result = budget_av->tda10021_set_frontend(fe, p);
933         if (budget_av->tda10021_ts_enabled) {
934                 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
935         } else {
936                 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
937         }
938
939         return result;
940 }
941
942 static void frontend_init(struct budget_av *budget_av)
943 {
944         struct saa7146_dev * saa = budget_av->budget.dev;
945         struct dvb_frontend * fe = NULL;
946
947         /* Enable / PowerON Frontend */
948         saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
949
950         /* additional setup necessary for the PLUS cards */
951         switch (saa->pci->subsystem_device) {
952                 case SUBID_DVBS_KNC1_PLUS:
953                 case SUBID_DVBC_KNC1_PLUS:
954                 case SUBID_DVBT_KNC1_PLUS:
955                         saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
956                         break;
957         }
958
959         switch (saa->pci->subsystem_device) {
960
961         case SUBID_DVBS_KNC1:
962         case SUBID_DVBS_KNC1_PLUS:
963         case SUBID_DVBS_EASYWATCH_1:
964                 if (saa->pci->subsystem_vendor == 0x1894) {
965                         fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
966                                              &budget_av->budget.i2c_adap);
967                         if (fe) {
968                                 dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
969                         }
970                 } else {
971                         fe = dvb_attach(stv0299_attach, &typhoon_config,
972                                              &budget_av->budget.i2c_adap);
973                         if (fe) {
974                                 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
975                         }
976                 }
977                 break;
978
979         case SUBID_DVBS_TV_STAR:
980         case SUBID_DVBS_TV_STAR_CI:
981         case SUBID_DVBS_CYNERGY1200N:
982         case SUBID_DVBS_EASYWATCH:
983                 fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
984                                 &budget_av->budget.i2c_adap);
985                 if (fe) {
986                         fe->ops.tuner_ops.set_params = philips_sd1878_tda8261_tuner_set_params;
987                 }
988                 break;
989
990         case SUBID_DVBS_TYPHOON:
991                 fe = dvb_attach(stv0299_attach, &typhoon_config,
992                                     &budget_av->budget.i2c_adap);
993                 if (fe) {
994                         fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
995                 }
996                 break;
997
998         case SUBID_DVBS_CINERGY1200:
999                 fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
1000                                     &budget_av->budget.i2c_adap);
1001                 if (fe) {
1002                         fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1003                 }
1004                 break;
1005
1006         case SUBID_DVBC_KNC1:
1007         case SUBID_DVBC_KNC1_PLUS:
1008         case SUBID_DVBC_CINERGY1200:
1009                 budget_av->reinitialise_demod = 1;
1010                 fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
1011                                      &budget_av->budget.i2c_adap,
1012                                      read_pwm(budget_av));
1013                 if (fe) {
1014                         budget_av->tda10021_poclkp = 1;
1015                         budget_av->tda10021_set_frontend = fe->ops.set_frontend;
1016                         fe->ops.set_frontend = tda10021_set_frontend;
1017                         fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1018                 }
1019                 break;
1020
1021         case SUBID_DVBT_KNC1:
1022         case SUBID_DVBT_KNC1_PLUS:
1023         case SUBID_DVBT_CINERGY1200:
1024                 budget_av->reinitialise_demod = 1;
1025                 fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
1026                                      &budget_av->budget.i2c_adap);
1027                 if (fe) {
1028                         fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1029                         fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
1030                 }
1031                 break;
1032         }
1033
1034         if (fe == NULL) {
1035                 printk(KERN_ERR "budget-av: A frontend driver was not found "
1036                                 "for device %04x/%04x subsystem %04x/%04x\n",
1037                        saa->pci->vendor,
1038                        saa->pci->device,
1039                        saa->pci->subsystem_vendor,
1040                        saa->pci->subsystem_device);
1041                 return;
1042         }
1043
1044         budget_av->budget.dvb_frontend = fe;
1045
1046         if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1047                                   budget_av->budget.dvb_frontend)) {
1048                 printk(KERN_ERR "budget-av: Frontend registration failed!\n");
1049                 dvb_frontend_detach(budget_av->budget.dvb_frontend);
1050                 budget_av->budget.dvb_frontend = NULL;
1051         }
1052 }
1053
1054
1055 static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1056 {
1057         struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1058
1059         dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1060
1061         if (*isr & MASK_10)
1062                 ttpci_budget_irq10_handler(dev, isr);
1063 }
1064
1065 static int budget_av_detach(struct saa7146_dev *dev)
1066 {
1067         struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1068         int err;
1069
1070         dprintk(2, "dev: %p\n", dev);
1071
1072         if (1 == budget_av->has_saa7113) {
1073                 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
1074
1075                 msleep(200);
1076
1077                 saa7146_unregister_device(&budget_av->vd, dev);
1078         }
1079
1080         if (budget_av->budget.ci_present)
1081                 ciintf_deinit(budget_av);
1082
1083         if (budget_av->budget.dvb_frontend != NULL) {
1084                 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
1085                 dvb_frontend_detach(budget_av->budget.dvb_frontend);
1086         }
1087         err = ttpci_budget_deinit(&budget_av->budget);
1088
1089         kfree(budget_av);
1090
1091         return err;
1092 }
1093
1094 static struct saa7146_ext_vv vv_data;
1095
1096 static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1097 {
1098         struct budget_av *budget_av;
1099         u8 *mac;
1100         int err;
1101
1102         dprintk(2, "dev: %p\n", dev);
1103
1104         if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
1105                 return -ENOMEM;
1106
1107         budget_av->has_saa7113 = 0;
1108         budget_av->budget.ci_present = 0;
1109
1110         dev->ext_priv = budget_av;
1111
1112         if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) {
1113                 kfree(budget_av);
1114                 return err;
1115         }
1116
1117         /* knc1 initialization */
1118         saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1119         saa7146_write(dev, DD1_INIT, 0x07000600);
1120         saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
1121
1122         if (saa7113_init(budget_av) == 0) {
1123                 budget_av->has_saa7113 = 1;
1124
1125                 if (0 != saa7146_vv_init(dev, &vv_data)) {
1126                         /* fixme: proper cleanup here */
1127                         ERR(("cannot init vv subsystem.\n"));
1128                         return err;
1129                 }
1130
1131                 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1132                         /* fixme: proper cleanup here */
1133                         ERR(("cannot register capture v4l2 device.\n"));
1134                         return err;
1135                 }
1136
1137                 /* beware: this modifies dev->vv ... */
1138                 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
1139                                                 SAA7146_HPS_SYNC_PORT_A);
1140
1141                 saa7113_setinput(budget_av, 0);
1142         }
1143
1144         /* fixme: find some sane values here... */
1145         saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1146
1147         mac = budget_av->budget.dvb_adapter.proposed_mac;
1148         if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
1149                 printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n",
1150                        budget_av->budget.dvb_adapter.num);
1151                 memset(mac, 0, 6);
1152         } else {
1153                 printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
1154                        budget_av->budget.dvb_adapter.num,
1155                        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1156         }
1157
1158         budget_av->budget.dvb_adapter.priv = budget_av;
1159         frontend_init(budget_av);
1160         ciintf_init(budget_av);
1161
1162         ttpci_budget_init_hooks(&budget_av->budget);
1163
1164         return 0;
1165 }
1166
1167 #define KNC1_INPUTS 2
1168 static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1169         {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1170         {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1171 };
1172
1173 static struct saa7146_extension_ioctls ioctls[] = {
1174         {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
1175         {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
1176         {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
1177         {0, 0}
1178 };
1179
1180 static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
1181 {
1182         struct saa7146_dev *dev = fh->dev;
1183         struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1184
1185         switch (cmd) {
1186         case VIDIOC_ENUMINPUT:{
1187                 struct v4l2_input *i = arg;
1188
1189                 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
1190                 if (i->index < 0 || i->index >= KNC1_INPUTS) {
1191                         return -EINVAL;
1192                 }
1193                 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1194                 return 0;
1195         }
1196         case VIDIOC_G_INPUT:{
1197                 int *input = (int *) arg;
1198
1199                 *input = budget_av->cur_input;
1200
1201                 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
1202                 return 0;
1203         }
1204         case VIDIOC_S_INPUT:{
1205                 int input = *(int *) arg;
1206                 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
1207                 return saa7113_setinput(budget_av, input);
1208         }
1209         default:
1210                 return -ENOIOCTLCMD;
1211         }
1212         return 0;
1213 }
1214
1215 static struct saa7146_standard standard[] = {
1216         {.name = "PAL",.id = V4L2_STD_PAL,
1217          .v_offset = 0x17,.v_field = 288,
1218          .h_offset = 0x14,.h_pixels = 680,
1219          .v_max_out = 576,.h_max_out = 768 },
1220
1221         {.name = "NTSC",.id = V4L2_STD_NTSC,
1222          .v_offset = 0x16,.v_field = 240,
1223          .h_offset = 0x06,.h_pixels = 708,
1224          .v_max_out = 480,.h_max_out = 640, },
1225 };
1226
1227 static struct saa7146_ext_vv vv_data = {
1228         .inputs = 2,
1229         .capabilities = 0,      // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
1230         .flags = 0,
1231         .stds = &standard[0],
1232         .num_stds = sizeof(standard) / sizeof(struct saa7146_standard),
1233         .ioctls = &ioctls[0],
1234         .ioctl = av_ioctl,
1235 };
1236
1237 static struct saa7146_extension budget_extension;
1238
1239 MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
1240 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1241 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
1242 MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
1243 MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
1244 MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
1245 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
1246 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
1247 MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
1248 MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1249 MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1250 MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
1251 MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1252
1253 static struct pci_device_id pci_tbl[] = {
1254         MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
1255         MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
1256         MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
1257         MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
1258         MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
1259         MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
1260         MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
1261         MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1262         MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1263         MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1264         MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
1265         MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
1266         MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
1267         MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
1268         MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
1269         MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
1270         MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1271         {
1272          .vendor = 0,
1273         }
1274 };
1275
1276 MODULE_DEVICE_TABLE(pci, pci_tbl);
1277
1278 static struct saa7146_extension budget_extension = {
1279         .name = "budget_av",
1280         .flags = SAA7146_I2C_SHORT_DELAY,
1281
1282         .pci_tbl = pci_tbl,
1283
1284         .module = THIS_MODULE,
1285         .attach = budget_av_attach,
1286         .detach = budget_av_detach,
1287
1288         .irq_mask = MASK_10,
1289         .irq_func = budget_av_irq,
1290 };
1291
1292 static int __init budget_av_init(void)
1293 {
1294         return saa7146_register_extension(&budget_extension);
1295 }
1296
1297 static void __exit budget_av_exit(void)
1298 {
1299         saa7146_unregister_extension(&budget_extension);
1300 }
1301
1302 module_init(budget_av_init);
1303 module_exit(budget_av_exit);
1304
1305 MODULE_LICENSE("GPL");
1306 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1307 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1308                    "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");