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