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