3459a9af7009c7f52f1d49463bdcf025ff30ef22
[safe/jmp/linux-2.6] / drivers / media / dvb / ttpci / budget-av.c
1 /*
2  * budget-av.c: driver for the SAA7146 based Budget DVB cards
3  *              with analog video in
4  *
5  * Compiled from various sources by Michael Hunold <michael@mihu.de>
6  *
7  * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
8  *                               Andrew de Quincey <adq_dvb@lidskialf.net>
9  *
10  * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
11  *
12  * Copyright (C) 1999-2002 Ralph  Metzler
13  *                       & Marcus Metzler for convergence integrated media GmbH
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
31  *
32  *
33  * the project's page is at http://www.linuxtv.org/dvb/
34  */
35
36 #include "budget.h"
37 #include "stv0299.h"
38 #include "stb0899_drv.h"
39 #include "stb0899_reg.h"
40 #include "tda8261.h"
41 #include "tda1002x.h"
42 #include "tda1004x.h"
43 #include "tua6100.h"
44 #include "dvb-pll.h"
45 #include <media/saa7146_vv.h>
46 #include <linux/module.h>
47 #include <linux/errno.h>
48 #include <linux/slab.h>
49 #include <linux/interrupt.h>
50 #include <linux/input.h>
51 #include <linux/spinlock.h>
52
53 #include "dvb_ca_en50221.h"
54
55 #define DEBICICAM               0x02420000
56
57 #define SLOTSTATUS_NONE         1
58 #define SLOTSTATUS_PRESENT      2
59 #define SLOTSTATUS_RESET        4
60 #define SLOTSTATUS_READY        8
61 #define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
62
63 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
64
65 struct budget_av {
66         struct budget budget;
67         struct video_device *vd;
68         int cur_input;
69         int has_saa7113;
70         struct tasklet_struct ciintf_irq_tasklet;
71         int slot_status;
72         struct dvb_ca_en50221 ca;
73         u8 reinitialise_demod:1;
74 };
75
76 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
77
78
79 /* GPIO Connections:
80  * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
81  * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
82  * 2 - CI Card Enable (Active Low)
83  * 3 - CI Card Detect
84  */
85
86 /****************************************************************************
87  * INITIALIZATION
88  ****************************************************************************/
89
90 static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
91 {
92         u8 mm1[] = { 0x00 };
93         u8 mm2[] = { 0x00 };
94         struct i2c_msg msgs[2];
95
96         msgs[0].flags = 0;
97         msgs[1].flags = I2C_M_RD;
98         msgs[0].addr = msgs[1].addr = id / 2;
99         mm1[0] = reg;
100         msgs[0].len = 1;
101         msgs[1].len = 1;
102         msgs[0].buf = mm1;
103         msgs[1].buf = mm2;
104
105         i2c_transfer(i2c, msgs, 2);
106
107         return mm2[0];
108 }
109
110 static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
111 {
112         u8 mm1[] = { reg };
113         struct i2c_msg msgs[2] = {
114                 {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
115                 {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
116         };
117
118         if (i2c_transfer(i2c, msgs, 2) != 2)
119                 return -EIO;
120
121         return 0;
122 }
123
124 static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
125 {
126         u8 msg[2] = { reg, val };
127         struct i2c_msg msgs;
128
129         msgs.flags = 0;
130         msgs.addr = id / 2;
131         msgs.len = 2;
132         msgs.buf = msg;
133         return i2c_transfer(i2c, &msgs, 1);
134 }
135
136 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
137 {
138         struct budget_av *budget_av = (struct budget_av *) ca->data;
139         int result;
140
141         if (slot != 0)
142                 return -EINVAL;
143
144         saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
145         udelay(1);
146
147         result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
148         if (result == -ETIMEDOUT) {
149                 ciintf_slot_shutdown(ca, slot);
150                 printk(KERN_INFO "budget-av: cam ejected 1\n");
151         }
152         return result;
153 }
154
155 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
156 {
157         struct budget_av *budget_av = (struct budget_av *) ca->data;
158         int result;
159
160         if (slot != 0)
161                 return -EINVAL;
162
163         saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
164         udelay(1);
165
166         result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
167         if (result == -ETIMEDOUT) {
168                 ciintf_slot_shutdown(ca, slot);
169                 printk(KERN_INFO "budget-av: cam ejected 2\n");
170         }
171         return result;
172 }
173
174 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
175 {
176         struct budget_av *budget_av = (struct budget_av *) ca->data;
177         int result;
178
179         if (slot != 0)
180                 return -EINVAL;
181
182         saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
183         udelay(1);
184
185         result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
186         if (result == -ETIMEDOUT) {
187                 ciintf_slot_shutdown(ca, slot);
188                 printk(KERN_INFO "budget-av: cam ejected 3\n");
189                 return -ETIMEDOUT;
190         }
191         return result;
192 }
193
194 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
195 {
196         struct budget_av *budget_av = (struct budget_av *) ca->data;
197         int result;
198
199         if (slot != 0)
200                 return -EINVAL;
201
202         saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
203         udelay(1);
204
205         result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
206         if (result == -ETIMEDOUT) {
207                 ciintf_slot_shutdown(ca, slot);
208                 printk(KERN_INFO "budget-av: cam ejected 5\n");
209         }
210         return result;
211 }
212
213 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
214 {
215         struct budget_av *budget_av = (struct budget_av *) ca->data;
216         struct saa7146_dev *saa = budget_av->budget.dev;
217
218         if (slot != 0)
219                 return -EINVAL;
220
221         dprintk(1, "ciintf_slot_reset\n");
222         budget_av->slot_status = SLOTSTATUS_RESET;
223
224         saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
225
226         saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
227         msleep(2);
228         saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
229         msleep(20); /* 20 ms Vcc settling time */
230
231         saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
232         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
233         msleep(20);
234
235         /* reinitialise the frontend if necessary */
236         if (budget_av->reinitialise_demod)
237                 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
238
239         return 0;
240 }
241
242 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
243 {
244         struct budget_av *budget_av = (struct budget_av *) ca->data;
245         struct saa7146_dev *saa = budget_av->budget.dev;
246
247         if (slot != 0)
248                 return -EINVAL;
249
250         dprintk(1, "ciintf_slot_shutdown\n");
251
252         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
253         budget_av->slot_status = SLOTSTATUS_NONE;
254
255         return 0;
256 }
257
258 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
259 {
260         struct budget_av *budget_av = (struct budget_av *) ca->data;
261         struct saa7146_dev *saa = budget_av->budget.dev;
262
263         if (slot != 0)
264                 return -EINVAL;
265
266         dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
267
268         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
269
270         return 0;
271 }
272
273 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
274 {
275         struct budget_av *budget_av = (struct budget_av *) ca->data;
276         struct saa7146_dev *saa = budget_av->budget.dev;
277         int result;
278
279         if (slot != 0)
280                 return -EINVAL;
281
282         /* test the card detect line - needs to be done carefully
283          * since it never goes high for some CAMs on this interface (e.g. topuptv) */
284         if (budget_av->slot_status == SLOTSTATUS_NONE) {
285                 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
286                 udelay(1);
287                 if (saa7146_read(saa, PSR) & MASK_06) {
288                         if (budget_av->slot_status == SLOTSTATUS_NONE) {
289                                 budget_av->slot_status = SLOTSTATUS_PRESENT;
290                                 printk(KERN_INFO "budget-av: cam inserted A\n");
291                         }
292                 }
293                 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
294         }
295
296         /* We also try and read from IO memory to work round the above detection bug. If
297          * there is no CAM, we will get a timeout. Only done if there is no cam
298          * present, since this test actually breaks some cams :(
299          *
300          * if the CI interface is not open, we also do the above test since we
301          * don't care if the cam has problems - we'll be resetting it on open() anyway */
302         if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
303                 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
304                 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
305                 if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
306                         budget_av->slot_status = SLOTSTATUS_PRESENT;
307                         printk(KERN_INFO "budget-av: cam inserted B\n");
308                 } else if (result < 0) {
309                         if (budget_av->slot_status != SLOTSTATUS_NONE) {
310                                 ciintf_slot_shutdown(ca, slot);
311                                 printk(KERN_INFO "budget-av: cam ejected 5\n");
312                                 return 0;
313                         }
314                 }
315         }
316
317         /* read from attribute memory in reset/ready state to know when the CAM is ready */
318         if (budget_av->slot_status == SLOTSTATUS_RESET) {
319                 result = ciintf_read_attribute_mem(ca, slot, 0);
320                 if (result == 0x1d) {
321                         budget_av->slot_status = SLOTSTATUS_READY;
322                 }
323         }
324
325         /* work out correct return code */
326         if (budget_av->slot_status != SLOTSTATUS_NONE) {
327                 if (budget_av->slot_status & SLOTSTATUS_READY) {
328                         return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
329                 }
330                 return DVB_CA_EN50221_POLL_CAM_PRESENT;
331         }
332         return 0;
333 }
334
335 static int ciintf_init(struct budget_av *budget_av)
336 {
337         struct saa7146_dev *saa = budget_av->budget.dev;
338         int result;
339
340         memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
341
342         saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
343         saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
344         saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
345         saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
346
347         /* Enable DEBI pins */
348         saa7146_write(saa, MC1, MASK_27 | MASK_11);
349
350         /* register CI interface */
351         budget_av->ca.owner = THIS_MODULE;
352         budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
353         budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
354         budget_av->ca.read_cam_control = ciintf_read_cam_control;
355         budget_av->ca.write_cam_control = ciintf_write_cam_control;
356         budget_av->ca.slot_reset = ciintf_slot_reset;
357         budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
358         budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
359         budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
360         budget_av->ca.data = budget_av;
361         budget_av->budget.ci_present = 1;
362         budget_av->slot_status = SLOTSTATUS_NONE;
363
364         if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
365                                           &budget_av->ca, 0, 1)) != 0) {
366                 printk(KERN_ERR "budget-av: ci initialisation failed.\n");
367                 goto error;
368         }
369
370         printk(KERN_INFO "budget-av: ci interface initialised.\n");
371         return 0;
372
373 error:
374         saa7146_write(saa, MC1, MASK_27);
375         return result;
376 }
377
378 static void ciintf_deinit(struct budget_av *budget_av)
379 {
380         struct saa7146_dev *saa = budget_av->budget.dev;
381
382         saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
383         saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
384         saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
385         saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
386
387         /* release the CA device */
388         dvb_ca_en50221_release(&budget_av->ca);
389
390         /* disable DEBI pins */
391         saa7146_write(saa, MC1, MASK_27);
392 }
393
394
395 static const u8 saa7113_tab[] = {
396         0x01, 0x08,
397         0x02, 0xc0,
398         0x03, 0x33,
399         0x04, 0x00,
400         0x05, 0x00,
401         0x06, 0xeb,
402         0x07, 0xe0,
403         0x08, 0x28,
404         0x09, 0x00,
405         0x0a, 0x80,
406         0x0b, 0x47,
407         0x0c, 0x40,
408         0x0d, 0x00,
409         0x0e, 0x01,
410         0x0f, 0x44,
411
412         0x10, 0x08,
413         0x11, 0x0c,
414         0x12, 0x7b,
415         0x13, 0x00,
416         0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
417
418         0x57, 0xff,
419         0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
420         0x5b, 0x83, 0x5e, 0x00,
421         0xff
422 };
423
424 static int saa7113_init(struct budget_av *budget_av)
425 {
426         struct budget *budget = &budget_av->budget;
427         struct saa7146_dev *saa = budget->dev;
428         const u8 *data = saa7113_tab;
429
430         saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
431         msleep(200);
432
433         if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
434                 dprintk(1, "saa7113 not found on KNC card\n");
435                 return -ENODEV;
436         }
437
438         dprintk(1, "saa7113 detected and initializing\n");
439
440         while (*data != 0xff) {
441                 i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
442                 data += 2;
443         }
444
445         dprintk(1, "saa7113  status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
446
447         return 0;
448 }
449
450 static int saa7113_setinput(struct budget_av *budget_av, int input)
451 {
452         struct budget *budget = &budget_av->budget;
453
454         if (1 != budget_av->has_saa7113)
455                 return -ENODEV;
456
457         if (input == 1) {
458                 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
459                 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
460         } else if (input == 0) {
461                 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
462                 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
463         } else
464                 return -EINVAL;
465
466         budget_av->cur_input = input;
467         return 0;
468 }
469
470
471 static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
472 {
473         u8 aclk = 0;
474         u8 bclk = 0;
475         u8 m1;
476
477         aclk = 0xb5;
478         if (srate < 2000000)
479                 bclk = 0x86;
480         else if (srate < 5000000)
481                 bclk = 0x89;
482         else if (srate < 15000000)
483                 bclk = 0x8f;
484         else if (srate < 45000000)
485                 bclk = 0x95;
486
487         m1 = 0x14;
488         if (srate < 4000000)
489                 m1 = 0x10;
490
491         stv0299_writereg(fe, 0x13, aclk);
492         stv0299_writereg(fe, 0x14, bclk);
493         stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
494         stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
495         stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
496         stv0299_writereg(fe, 0x0f, 0x80 | m1);
497
498         return 0;
499 }
500
501 static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe,
502                                                  struct dvb_frontend_parameters *params)
503 {
504         u32 div;
505         u8 buf[4];
506         struct budget *budget = (struct budget *) fe->dvb->priv;
507         struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
508
509         if ((params->frequency < 950000) || (params->frequency > 2150000))
510                 return -EINVAL;
511
512         div = (params->frequency + (125 - 1)) / 125;    // round correctly
513         buf[0] = (div >> 8) & 0x7f;
514         buf[1] = div & 0xff;
515         buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
516         buf[3] = 0x20;
517
518         if (params->u.qpsk.symbol_rate < 4000000)
519                 buf[3] |= 1;
520
521         if (params->frequency < 1250000)
522                 buf[3] |= 0;
523         else if (params->frequency < 1550000)
524                 buf[3] |= 0x40;
525         else if (params->frequency < 2050000)
526                 buf[3] |= 0x80;
527         else if (params->frequency < 2150000)
528                 buf[3] |= 0xC0;
529
530         if (fe->ops.i2c_gate_ctrl)
531                 fe->ops.i2c_gate_ctrl(fe, 1);
532         if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
533                 return -EIO;
534         return 0;
535 }
536
537 static u8 typhoon_cinergy1200s_inittab[] = {
538         0x01, 0x15,
539         0x02, 0x30,
540         0x03, 0x00,
541         0x04, 0x7d,             /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
542         0x05, 0x35,             /* I2CT = 0, SCLT = 1, SDAT = 1 */
543         0x06, 0x40,             /* DAC not used, set to high impendance mode */
544         0x07, 0x00,             /* DAC LSB */
545         0x08, 0x40,             /* DiSEqC off */
546         0x09, 0x00,             /* FIFO */
547         0x0c, 0x51,             /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
548         0x0d, 0x82,             /* DC offset compensation = ON, beta_agc1 = 2 */
549         0x0e, 0x23,             /* alpha_tmg = 2, beta_tmg = 3 */
550         0x10, 0x3f,             // AGC2  0x3d
551         0x11, 0x84,
552         0x12, 0xb9,
553         0x15, 0xc9,             // lock detector threshold
554         0x16, 0x00,
555         0x17, 0x00,
556         0x18, 0x00,
557         0x19, 0x00,
558         0x1a, 0x00,
559         0x1f, 0x50,
560         0x20, 0x00,
561         0x21, 0x00,
562         0x22, 0x00,
563         0x23, 0x00,
564         0x28, 0x00,             // out imp: normal  out type: parallel FEC mode:0
565         0x29, 0x1e,             // 1/2 threshold
566         0x2a, 0x14,             // 2/3 threshold
567         0x2b, 0x0f,             // 3/4 threshold
568         0x2c, 0x09,             // 5/6 threshold
569         0x2d, 0x05,             // 7/8 threshold
570         0x2e, 0x01,
571         0x31, 0x1f,             // test all FECs
572         0x32, 0x19,             // viterbi and synchro search
573         0x33, 0xfc,             // rs control
574         0x34, 0x93,             // error control
575         0x0f, 0x92,
576         0xff, 0xff
577 };
578
579 static struct stv0299_config typhoon_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_1,
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
592 static struct stv0299_config cinergy_1200s_config = {
593         .demod_address = 0x68,
594         .inittab = typhoon_cinergy1200s_inittab,
595         .mclk = 88000000UL,
596         .invert = 0,
597         .skip_reinit = 0,
598         .lock_output = STV0299_LOCKOUTPUT_0,
599         .volt13_op0_op1 = STV0299_VOLT13_OP0,
600         .min_delay_ms = 100,
601         .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
602 };
603
604 static struct stv0299_config cinergy_1200s_1894_0010_config = {
605         .demod_address = 0x68,
606         .inittab = typhoon_cinergy1200s_inittab,
607         .mclk = 88000000UL,
608         .invert = 1,
609         .skip_reinit = 0,
610         .lock_output = STV0299_LOCKOUTPUT_1,
611         .volt13_op0_op1 = STV0299_VOLT13_OP0,
612         .min_delay_ms = 100,
613         .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
614 };
615
616 static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
617 {
618         struct budget *budget = (struct budget *) fe->dvb->priv;
619         u8 buf[6];
620         struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
621         int i;
622
623 #define CU1216_IF 36125000
624 #define TUNER_MUL 62500
625
626         u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
627
628         buf[0] = (div >> 8) & 0x7f;
629         buf[1] = div & 0xff;
630         buf[2] = 0xce;
631         buf[3] = (params->frequency < 150000000 ? 0x01 :
632                   params->frequency < 445000000 ? 0x02 : 0x04);
633         buf[4] = 0xde;
634         buf[5] = 0x20;
635
636         if (fe->ops.i2c_gate_ctrl)
637                 fe->ops.i2c_gate_ctrl(fe, 1);
638         if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
639                 return -EIO;
640
641         /* wait for the pll lock */
642         msg.flags = I2C_M_RD;
643         msg.len = 1;
644         for (i = 0; i < 20; i++) {
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 && (buf[0] & 0x40))
648                         break;
649                 msleep(10);
650         }
651
652         /* switch the charge pump to the lower current */
653         msg.flags = 0;
654         msg.len = 2;
655         msg.buf = &buf[2];
656         buf[2] &= ~0x40;
657         if (fe->ops.i2c_gate_ctrl)
658                 fe->ops.i2c_gate_ctrl(fe, 1);
659         if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
660                 return -EIO;
661
662         return 0;
663 }
664
665 static struct tda1002x_config philips_cu1216_config = {
666         .demod_address = 0x0c,
667         .invert = 1,
668 };
669
670 static struct tda1002x_config philips_cu1216_config_altaddress = {
671         .demod_address = 0x0d,
672         .invert = 0,
673 };
674
675 static struct tda10023_config philips_cu1216_tda10023_config = {
676         .demod_address = 0x0c,
677         .invert = 1,
678 };
679
680 static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
681 {
682         struct budget *budget = (struct budget *) fe->dvb->priv;
683         static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
684         struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
685
686         // setup PLL configuration
687         if (fe->ops.i2c_gate_ctrl)
688                 fe->ops.i2c_gate_ctrl(fe, 1);
689         if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
690                 return -EIO;
691         msleep(1);
692
693         return 0;
694 }
695
696 static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
697 {
698         struct budget *budget = (struct budget *) fe->dvb->priv;
699         u8 tuner_buf[4];
700         struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
701                         sizeof(tuner_buf) };
702         int tuner_frequency = 0;
703         u8 band, cp, filter;
704
705         // determine charge pump
706         tuner_frequency = params->frequency + 36166000;
707         if (tuner_frequency < 87000000)
708                 return -EINVAL;
709         else if (tuner_frequency < 130000000)
710                 cp = 3;
711         else if (tuner_frequency < 160000000)
712                 cp = 5;
713         else if (tuner_frequency < 200000000)
714                 cp = 6;
715         else if (tuner_frequency < 290000000)
716                 cp = 3;
717         else if (tuner_frequency < 420000000)
718                 cp = 5;
719         else if (tuner_frequency < 480000000)
720                 cp = 6;
721         else if (tuner_frequency < 620000000)
722                 cp = 3;
723         else if (tuner_frequency < 830000000)
724                 cp = 5;
725         else if (tuner_frequency < 895000000)
726                 cp = 7;
727         else
728                 return -EINVAL;
729
730         // determine band
731         if (params->frequency < 49000000)
732                 return -EINVAL;
733         else if (params->frequency < 161000000)
734                 band = 1;
735         else if (params->frequency < 444000000)
736                 band = 2;
737         else if (params->frequency < 861000000)
738                 band = 4;
739         else
740                 return -EINVAL;
741
742         // setup PLL filter
743         switch (params->u.ofdm.bandwidth) {
744         case BANDWIDTH_6_MHZ:
745                 filter = 0;
746                 break;
747
748         case BANDWIDTH_7_MHZ:
749                 filter = 0;
750                 break;
751
752         case BANDWIDTH_8_MHZ:
753                 filter = 1;
754                 break;
755
756         default:
757                 return -EINVAL;
758         }
759
760         // calculate divisor
761         // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
762         tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
763
764         // setup tuner buffer
765         tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
766         tuner_buf[1] = tuner_frequency & 0xff;
767         tuner_buf[2] = 0xca;
768         tuner_buf[3] = (cp << 5) | (filter << 3) | band;
769
770         if (fe->ops.i2c_gate_ctrl)
771                 fe->ops.i2c_gate_ctrl(fe, 1);
772         if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
773                 return -EIO;
774
775         msleep(1);
776         return 0;
777 }
778
779 static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
780                                            const struct firmware **fw, char *name)
781 {
782         struct budget *budget = (struct budget *) fe->dvb->priv;
783
784         return request_firmware(fw, name, &budget->dev->pci->dev);
785 }
786
787 static struct tda1004x_config philips_tu1216_config = {
788
789         .demod_address = 0x8,
790         .invert = 1,
791         .invert_oclk = 1,
792         .xtal_freq = TDA10046_XTAL_4M,
793         .agc_config = TDA10046_AGC_DEFAULT,
794         .if_freq = TDA10046_FREQ_3617,
795         .request_firmware = philips_tu1216_request_firmware,
796 };
797
798 static u8 philips_sd1878_inittab[] = {
799         0x01, 0x15,
800         0x02, 0x30,
801         0x03, 0x00,
802         0x04, 0x7d,
803         0x05, 0x35,
804         0x06, 0x40,
805         0x07, 0x00,
806         0x08, 0x43,
807         0x09, 0x02,
808         0x0C, 0x51,
809         0x0D, 0x82,
810         0x0E, 0x23,
811         0x10, 0x3f,
812         0x11, 0x84,
813         0x12, 0xb9,
814         0x15, 0xc9,
815         0x16, 0x19,
816         0x17, 0x8c,
817         0x18, 0x59,
818         0x19, 0xf8,
819         0x1a, 0xfe,
820         0x1c, 0x7f,
821         0x1d, 0x00,
822         0x1e, 0x00,
823         0x1f, 0x50,
824         0x20, 0x00,
825         0x21, 0x00,
826         0x22, 0x00,
827         0x23, 0x00,
828         0x28, 0x00,
829         0x29, 0x28,
830         0x2a, 0x14,
831         0x2b, 0x0f,
832         0x2c, 0x09,
833         0x2d, 0x09,
834         0x31, 0x1f,
835         0x32, 0x19,
836         0x33, 0xfc,
837         0x34, 0x93,
838         0xff, 0xff
839 };
840
841 static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
842                 u32 srate, u32 ratio)
843 {
844         u8 aclk = 0;
845         u8 bclk = 0;
846         u8 m1;
847
848         aclk = 0xb5;
849         if (srate < 2000000)
850                 bclk = 0x86;
851         else if (srate < 5000000)
852                 bclk = 0x89;
853         else if (srate < 15000000)
854                 bclk = 0x8f;
855         else if (srate < 45000000)
856                 bclk = 0x95;
857
858         m1 = 0x14;
859         if (srate < 4000000)
860                 m1 = 0x10;
861
862         stv0299_writereg(fe, 0x0e, 0x23);
863         stv0299_writereg(fe, 0x0f, 0x94);
864         stv0299_writereg(fe, 0x10, 0x39);
865         stv0299_writereg(fe, 0x13, aclk);
866         stv0299_writereg(fe, 0x14, bclk);
867         stv0299_writereg(fe, 0x15, 0xc9);
868         stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
869         stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
870         stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
871         stv0299_writereg(fe, 0x0f, 0x80 | m1);
872
873         return 0;
874 }
875
876 static struct stv0299_config philips_sd1878_config = {
877         .demod_address = 0x68,
878      .inittab = philips_sd1878_inittab,
879         .mclk = 88000000UL,
880         .invert = 0,
881         .skip_reinit = 0,
882         .lock_output = STV0299_LOCKOUTPUT_1,
883         .volt13_op0_op1 = STV0299_VOLT13_OP0,
884         .min_delay_ms = 100,
885         .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
886 };
887
888 /* KNC1 DVB-S (STB0899) Inittab */
889 static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
890
891 //       0x0000000b ,   /* SYSREG */
892         { STB0899_DEV_ID                , 0x81 },
893         { STB0899_DISCNTRL1             , 0x32 },
894         { STB0899_DISCNTRL2             , 0x80 },
895         { STB0899_DISRX_ST0             , 0x04 },
896         { STB0899_DISRX_ST1             , 0x00 },
897         { STB0899_DISPARITY             , 0x00 },
898         { STB0899_DISFIFO               , 0x00 },
899         { STB0899_DISSTATUS             , 0x20 },
900         { STB0899_DISF22                , 0x8c },
901         { STB0899_DISF22RX              , 0x9a },
902         //SYSREG ?
903         { STB0899_ACRPRESC              , 0x11 },
904         { STB0899_ACRDIV1               , 0x0a },
905         { STB0899_ACRDIV2               , 0x05 },
906         { STB0899_DACR1                 , 0x00 },
907         { STB0899_DACR2                 , 0x00 },
908         { STB0899_OUTCFG                , 0x00 },
909         { STB0899_MODECFG               , 0x00 },
910         { STB0899_IRQSTATUS_3           , 0x30 },
911         { STB0899_IRQSTATUS_2           , 0x00 },
912         { STB0899_IRQSTATUS_1           , 0x00 },
913         { STB0899_IRQSTATUS_0           , 0x00 },
914         { STB0899_IRQMSK_3              , 0xf3 },
915         { STB0899_IRQMSK_2              , 0xfc },
916         { STB0899_IRQMSK_1              , 0xff },
917         { STB0899_IRQMSK_0              , 0xff },
918         { STB0899_IRQCFG                , 0x00 },
919         { STB0899_I2CCFG                , 0x88 },
920         { STB0899_I2CRPT                , 0x5c },
921         { STB0899_IOPVALUE5             , 0x00 },
922         { STB0899_IOPVALUE4             , 0x20 },
923         { STB0899_IOPVALUE3             , 0xc9 },
924         { STB0899_IOPVALUE2             , 0x90 },
925         { STB0899_IOPVALUE1             , 0x40 },
926         { STB0899_IOPVALUE0             , 0x00 },
927         { STB0899_GPIO00CFG             , 0x82 },
928         { STB0899_GPIO01CFG             , 0x82 },
929         { STB0899_GPIO02CFG             , 0x82 },
930         { STB0899_GPIO03CFG             , 0x82 },
931         { STB0899_GPIO04CFG             , 0x82 },
932         { STB0899_GPIO05CFG             , 0x82 },
933         { STB0899_GPIO06CFG             , 0x82 },
934         { STB0899_GPIO07CFG             , 0x82 },
935         { STB0899_GPIO08CFG             , 0x82 },
936         { STB0899_GPIO09CFG             , 0x82 },
937         { STB0899_GPIO10CFG             , 0x82 },
938         { STB0899_GPIO11CFG             , 0x82 },
939         { STB0899_GPIO12CFG             , 0x82 },
940         { STB0899_GPIO13CFG             , 0x82 },
941         { STB0899_GPIO14CFG             , 0x82 },
942         { STB0899_GPIO15CFG             , 0x82 },
943         { STB0899_GPIO16CFG             , 0x82 },
944         { STB0899_GPIO17CFG             , 0x82 },
945         { STB0899_GPIO18CFG             , 0x82 },
946         { STB0899_GPIO19CFG             , 0x82 },
947         { STB0899_GPIO20CFG             , 0x82 },
948         { STB0899_SDATCFG               , 0xb8 },
949         { STB0899_SCLTCFG               , 0xba },
950         { STB0899_AGCRFCFG              , 0x08 }, /* 0x1c */
951         { STB0899_GPIO22                , 0x82 }, /* AGCBB2CFG */
952         { STB0899_GPIO21                , 0x91 }, /* AGCBB1CFG */
953         { STB0899_DIRCLKCFG             , 0x82 },
954         { STB0899_CLKOUT27CFG           , 0x7e },
955         { STB0899_STDBYCFG              , 0x82 },
956         { STB0899_CS0CFG                , 0x82 },
957         { STB0899_CS1CFG                , 0x82 },
958         { STB0899_DISEQCOCFG            , 0x20 },
959         { STB0899_GPIO32CFG             , 0x82 },
960         { STB0899_GPIO33CFG             , 0x82 },
961         { STB0899_GPIO34CFG             , 0x82 },
962         { STB0899_GPIO35CFG             , 0x82 },
963         { STB0899_GPIO36CFG             , 0x82 },
964         { STB0899_GPIO37CFG             , 0x82 },
965         { STB0899_GPIO38CFG             , 0x82 },
966         { STB0899_GPIO39CFG             , 0x82 },
967         { STB0899_NCOARSE               , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
968         { STB0899_SYNTCTRL              , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
969         { STB0899_FILTCTRL              , 0x00 },
970         { STB0899_SYSCTRL               , 0x00 },
971         { STB0899_STOPCLK1              , 0x20 },
972         { STB0899_STOPCLK2              , 0x00 },
973         { STB0899_INTBUFSTATUS          , 0x00 },
974         { STB0899_INTBUFCTRL            , 0x0a },
975         { 0xffff                        , 0xff },
976 };
977
978 static const struct stb0899_s2_reg  knc1_stb0899_s2_init_2[] = {
979
980         { STB0899_OFF0_DMD_STATUS       , STB0899_BASE_DMD_STATUS       , 0x00000103 }, /* DMDSTATUS    */
981         { STB0899_OFF0_CRL_FREQ         , STB0899_BASE_CRL_FREQ         , 0x3ed1da56 }, /* CRLFREQ      */
982         { STB0899_OFF0_BTR_FREQ         , STB0899_BASE_BTR_FREQ         , 0x00004000 }, /* BTRFREQ      */
983         { STB0899_OFF0_IF_AGC_GAIN      , STB0899_BASE_IF_AGC_GAIN      , 0x00002ade }, /* IFAGCGAIN    */
984         { STB0899_OFF0_BB_AGC_GAIN      , STB0899_BASE_BB_AGC_GAIN      , 0x000001bc }, /* BBAGCGAIN    */
985         { STB0899_OFF0_DC_OFFSET        , STB0899_BASE_DC_OFFSET        , 0x00000200 }, /* DCOFFSET     */
986         { STB0899_OFF0_DMD_CNTRL        , STB0899_BASE_DMD_CNTRL        , 0x0000000f }, /* DMDCNTRL     */
987
988         { STB0899_OFF0_IF_AGC_CNTRL     , STB0899_BASE_IF_AGC_CNTRL     , 0x03fb4a20 }, /* IFAGCCNTRL   */
989         { STB0899_OFF0_BB_AGC_CNTRL     , STB0899_BASE_BB_AGC_CNTRL     , 0x00200c97 }, /* BBAGCCNTRL   */
990
991         { STB0899_OFF0_CRL_CNTRL        , STB0899_BASE_CRL_CNTRL        , 0x00000016 }, /* CRLCNTRL     */
992         { STB0899_OFF0_CRL_PHS_INIT     , STB0899_BASE_CRL_PHS_INIT     , 0x00000000 }, /* CRLPHSINIT   */
993         { STB0899_OFF0_CRL_FREQ_INIT    , STB0899_BASE_CRL_FREQ_INIT    , 0x00000000 }, /* CRLFREQINIT  */
994         { STB0899_OFF0_CRL_LOOP_GAIN    , STB0899_BASE_CRL_LOOP_GAIN    , 0x00000000 }, /* CRLLOOPGAIN  */
995         { STB0899_OFF0_CRL_NOM_FREQ     , STB0899_BASE_CRL_NOM_FREQ     , 0x3ed097b6 }, /* CRLNOMFREQ   */
996         { STB0899_OFF0_CRL_SWP_RATE     , STB0899_BASE_CRL_SWP_RATE     , 0x00000000 }, /* CRLSWPRATE   */
997         { STB0899_OFF0_CRL_MAX_SWP      , STB0899_BASE_CRL_MAX_SWP      , 0x00000000 }, /* CRLMAXSWP    */
998         { STB0899_OFF0_CRL_LK_CNTRL     , STB0899_BASE_CRL_LK_CNTRL     , 0x0f6cdc01 }, /* CRLLKCNTRL   */
999         { STB0899_OFF0_DECIM_CNTRL      , STB0899_BASE_DECIM_CNTRL      , 0x00000000 }, /* DECIMCNTRL   */
1000         { STB0899_OFF0_BTR_CNTRL        , STB0899_BASE_BTR_CNTRL        , 0x00003993 }, /* BTRCNTRL     */
1001         { STB0899_OFF0_BTR_LOOP_GAIN    , STB0899_BASE_BTR_LOOP_GAIN    , 0x000d3c6f }, /* BTRLOOPGAIN  */
1002         { STB0899_OFF0_BTR_PHS_INIT     , STB0899_BASE_BTR_PHS_INIT     , 0x00000000 }, /* BTRPHSINIT   */
1003         { STB0899_OFF0_BTR_FREQ_INIT    , STB0899_BASE_BTR_FREQ_INIT    , 0x00000000 }, /* BTRFREQINIT  */
1004         { STB0899_OFF0_BTR_NOM_FREQ     , STB0899_BASE_BTR_NOM_FREQ     , 0x0238e38e }, /* BTRNOMFREQ   */
1005         { STB0899_OFF0_BTR_LK_CNTRL     , STB0899_BASE_BTR_LK_CNTRL     , 0x00000000 }, /* BTRLKCNTRL   */
1006         { STB0899_OFF0_DECN_CNTRL       , STB0899_BASE_DECN_CNTRL       , 0x00000000 }, /* DECNCNTRL    */
1007         { STB0899_OFF0_TP_CNTRL         , STB0899_BASE_TP_CNTRL         , 0x00000000 }, /* TPCNTRL      */
1008         { STB0899_OFF0_TP_BUF_STATUS    , STB0899_BASE_TP_BUF_STATUS    , 0x00000000 }, /* TPBUFSTATUS  */
1009         { STB0899_OFF0_DC_ESTIM         , STB0899_BASE_DC_ESTIM         , 0x00000000 }, /* DCESTIM      */
1010         { STB0899_OFF0_FLL_CNTRL        , STB0899_BASE_FLL_CNTRL        , 0x00000000 }, /* FLLCNTRL     */
1011         { STB0899_OFF0_FLL_FREQ_WD      , STB0899_BASE_FLL_FREQ_WD      , 0x40070000 }, /* FLLFREQWD    */
1012         { STB0899_OFF0_ANTI_ALIAS_SEL   , STB0899_BASE_ANTI_ALIAS_SEL   , 0x00000001 }, /* ANTIALIASSEL */
1013         { STB0899_OFF0_RRC_ALPHA        , STB0899_BASE_RRC_ALPHA        , 0x00000002 }, /* RRCALPHA     */
1014         { STB0899_OFF0_DC_ADAPT_LSHFT   , STB0899_BASE_DC_ADAPT_LSHFT   , 0x00000000 }, /* DCADAPTISHFT */
1015         { STB0899_OFF0_IMB_OFFSET       , STB0899_BASE_IMB_OFFSET       , 0x0000fe01 }, /* IMBOFFSET    */
1016         { STB0899_OFF0_IMB_ESTIMATE     , STB0899_BASE_IMB_ESTIMATE     , 0x00000000 }, /* IMBESTIMATE  */
1017         { STB0899_OFF0_IMB_CNTRL        , STB0899_BASE_IMB_CNTRL        , 0x00000001 }, /* IMBCNTRL     */
1018         { STB0899_OFF0_IF_AGC_CNTRL2    , STB0899_BASE_IF_AGC_CNTRL2    , 0x00005007 }, /* IFAGCCNTRL2  */
1019         { STB0899_OFF0_DMD_CNTRL2       , STB0899_BASE_DMD_CNTRL2       , 0x00000002 }, /* DMDCNTRL2    */
1020         { STB0899_OFF0_TP_BUFFER        , STB0899_BASE_TP_BUFFER        , 0x00000000 }, /* TPBUFFER     */
1021         { STB0899_OFF0_TP_BUFFER1       , STB0899_BASE_TP_BUFFER1       , 0x00000000 }, /* TPBUFFER1    */
1022         { STB0899_OFF0_TP_BUFFER2       , STB0899_BASE_TP_BUFFER2       , 0x00000000 }, /* TPBUFFER2    */
1023         { STB0899_OFF0_TP_BUFFER3       , STB0899_BASE_TP_BUFFER3       , 0x00000000 }, /* TPBUFFER3    */
1024         { STB0899_OFF0_TP_BUFFER4       , STB0899_BASE_TP_BUFFER4       , 0x00000000 }, /* TPBUFFER4    */
1025         { STB0899_OFF0_TP_BUFFER5       , STB0899_BASE_TP_BUFFER5       , 0x00000000 }, /* TPBUFFER5    */
1026         { STB0899_OFF0_TP_BUFFER6       , STB0899_BASE_TP_BUFFER6       , 0x00000000 }, /* TPBUFFER6    */
1027         { STB0899_OFF0_TP_BUFFER7       , STB0899_BASE_TP_BUFFER7       , 0x00000000 }, /* TPBUFFER7    */
1028         { STB0899_OFF0_TP_BUFFER8       , STB0899_BASE_TP_BUFFER8       , 0x00000000 }, /* TPBUFFER8    */
1029         { STB0899_OFF0_TP_BUFFER9       , STB0899_BASE_TP_BUFFER9       , 0x00000000 }, /* TPBUFFER9    */
1030         { STB0899_OFF0_TP_BUFFER10      , STB0899_BASE_TP_BUFFER10      , 0x00000000 }, /* TPBUFFER10   */
1031         { STB0899_OFF0_TP_BUFFER11      , STB0899_BASE_TP_BUFFER11      , 0x00000000 }, /* TPBUFFER11   */
1032         { STB0899_OFF0_TP_BUFFER12      , STB0899_BASE_TP_BUFFER12      , 0x00000000 }, /* TPBUFFER12   */
1033         { STB0899_OFF0_TP_BUFFER13      , STB0899_BASE_TP_BUFFER13      , 0x00000000 }, /* TPBUFFER13   */
1034         { STB0899_OFF0_TP_BUFFER14      , STB0899_BASE_TP_BUFFER14      , 0x00000000 }, /* TPBUFFER14   */
1035         { STB0899_OFF0_TP_BUFFER15      , STB0899_BASE_TP_BUFFER15      , 0x00000000 }, /* TPBUFFER15   */
1036         { STB0899_OFF0_TP_BUFFER16      , STB0899_BASE_TP_BUFFER16      , 0x0000ff00 }, /* TPBUFFER16   */
1037         { STB0899_OFF0_TP_BUFFER17      , STB0899_BASE_TP_BUFFER17      , 0x00000100 }, /* TPBUFFER17   */
1038         { STB0899_OFF0_TP_BUFFER18      , STB0899_BASE_TP_BUFFER18      , 0x0000fe01 }, /* TPBUFFER18   */
1039         { STB0899_OFF0_TP_BUFFER19      , STB0899_BASE_TP_BUFFER19      , 0x000004fe }, /* TPBUFFER19   */
1040         { STB0899_OFF0_TP_BUFFER20      , STB0899_BASE_TP_BUFFER20      , 0x0000cfe7 }, /* TPBUFFER20   */
1041         { STB0899_OFF0_TP_BUFFER21      , STB0899_BASE_TP_BUFFER21      , 0x0000bec6 }, /* TPBUFFER21   */
1042         { STB0899_OFF0_TP_BUFFER22      , STB0899_BASE_TP_BUFFER22      , 0x0000c2bf }, /* TPBUFFER22   */
1043         { STB0899_OFF0_TP_BUFFER23      , STB0899_BASE_TP_BUFFER23      , 0x0000c1c1 }, /* TPBUFFER23   */
1044         { STB0899_OFF0_TP_BUFFER24      , STB0899_BASE_TP_BUFFER24      , 0x0000c1c1 }, /* TPBUFFER24   */
1045         { STB0899_OFF0_TP_BUFFER25      , STB0899_BASE_TP_BUFFER25      , 0x0000c1c1 }, /* TPBUFFER25   */
1046         { STB0899_OFF0_TP_BUFFER26      , STB0899_BASE_TP_BUFFER26      , 0x0000c1c1 }, /* TPBUFFER26   */
1047         { STB0899_OFF0_TP_BUFFER27      , STB0899_BASE_TP_BUFFER27      , 0x0000c1c0 }, /* TPBUFFER27   */
1048         { STB0899_OFF0_TP_BUFFER28      , STB0899_BASE_TP_BUFFER28      , 0x0000c0c0 }, /* TPBUFFER28   */
1049         { STB0899_OFF0_TP_BUFFER29      , STB0899_BASE_TP_BUFFER29      , 0x0000c1c1 }, /* TPBUFFER29   */
1050         { STB0899_OFF0_TP_BUFFER30      , STB0899_BASE_TP_BUFFER30      , 0x0000c1c1 }, /* TPBUFFER30   */
1051         { STB0899_OFF0_TP_BUFFER31      , STB0899_BASE_TP_BUFFER31      , 0x0000c0c1 }, /* TPBUFFER31   */
1052         { STB0899_OFF0_TP_BUFFER32      , STB0899_BASE_TP_BUFFER32      , 0x0000c0c1 }, /* TPBUFFER32   */
1053         { STB0899_OFF0_TP_BUFFER33      , STB0899_BASE_TP_BUFFER33      , 0x0000c1c1 }, /* TPBUFFER33   */
1054         { STB0899_OFF0_TP_BUFFER34      , STB0899_BASE_TP_BUFFER34      , 0x0000c1c1 }, /* TPBUFFER34   */
1055         { STB0899_OFF0_TP_BUFFER35      , STB0899_BASE_TP_BUFFER35      , 0x0000c0c1 }, /* TPBUFFER35   */
1056         { STB0899_OFF0_TP_BUFFER36      , STB0899_BASE_TP_BUFFER36      , 0x0000c1c1 }, /* TPBUFFER36   */
1057         { STB0899_OFF0_TP_BUFFER37      , STB0899_BASE_TP_BUFFER37      , 0x0000c0c1 }, /* TPBUFFER37   */
1058         { STB0899_OFF0_TP_BUFFER38      , STB0899_BASE_TP_BUFFER38      , 0x0000c1c1 }, /* TPBUFFER38   */
1059         { STB0899_OFF0_TP_BUFFER39      , STB0899_BASE_TP_BUFFER39      , 0x0000c0c0 }, /* TPBUFFER39   */
1060         { STB0899_OFF0_TP_BUFFER40      , STB0899_BASE_TP_BUFFER40      , 0x0000c1c0 }, /* TPBUFFER40   */
1061         { STB0899_OFF0_TP_BUFFER41      , STB0899_BASE_TP_BUFFER41      , 0x0000c1c1 }, /* TPBUFFER41   */
1062         { STB0899_OFF0_TP_BUFFER42      , STB0899_BASE_TP_BUFFER42      , 0x0000c0c0 }, /* TPBUFFER42   */
1063         { STB0899_OFF0_TP_BUFFER43      , STB0899_BASE_TP_BUFFER43      , 0x0000c1c0 }, /* TPBUFFER43   */
1064         { STB0899_OFF0_TP_BUFFER44      , STB0899_BASE_TP_BUFFER44      , 0x0000c0c1 }, /* TPBUFFER44   */
1065         { STB0899_OFF0_TP_BUFFER45      , STB0899_BASE_TP_BUFFER45      , 0x0000c1be }, /* TPBUFFER45   */
1066         { STB0899_OFF0_TP_BUFFER46      , STB0899_BASE_TP_BUFFER46      , 0x0000c1c9 }, /* TPBUFFER46   */
1067         { STB0899_OFF0_TP_BUFFER47      , STB0899_BASE_TP_BUFFER47      , 0x0000c0da }, /* TPBUFFER47   */
1068         { STB0899_OFF0_TP_BUFFER48      , STB0899_BASE_TP_BUFFER48      , 0x0000c0ba }, /* TPBUFFER48   */
1069         { STB0899_OFF0_TP_BUFFER49      , STB0899_BASE_TP_BUFFER49      , 0x0000c1c4 }, /* TPBUFFER49   */
1070         { STB0899_OFF0_TP_BUFFER50      , STB0899_BASE_TP_BUFFER50      , 0x0000c1bf }, /* TPBUFFER50   */
1071         { STB0899_OFF0_TP_BUFFER51      , STB0899_BASE_TP_BUFFER51      , 0x0000c0c1 }, /* TPBUFFER51   */
1072         { STB0899_OFF0_TP_BUFFER52      , STB0899_BASE_TP_BUFFER52      , 0x0000c1c0 }, /* TPBUFFER52   */
1073         { STB0899_OFF0_TP_BUFFER53      , STB0899_BASE_TP_BUFFER53      , 0x0000c0c1 }, /* TPBUFFER53   */
1074         { STB0899_OFF0_TP_BUFFER54      , STB0899_BASE_TP_BUFFER54      , 0x0000c1c1 }, /* TPBUFFER54   */
1075         { STB0899_OFF0_TP_BUFFER55      , STB0899_BASE_TP_BUFFER55      , 0x0000c1c1 }, /* TPBUFFER55   */
1076         { STB0899_OFF0_TP_BUFFER56      , STB0899_BASE_TP_BUFFER56      , 0x0000c1c1 }, /* TPBUFFER56   */
1077         { STB0899_OFF0_TP_BUFFER57      , STB0899_BASE_TP_BUFFER57      , 0x0000c1c1 }, /* TPBUFFER57   */
1078         { STB0899_OFF0_TP_BUFFER58      , STB0899_BASE_TP_BUFFER58      , 0x0000c1c1 }, /* TPBUFFER58   */
1079         { STB0899_OFF0_TP_BUFFER59      , STB0899_BASE_TP_BUFFER59      , 0x0000c1c1 }, /* TPBUFFER59   */
1080         { STB0899_OFF0_TP_BUFFER60      , STB0899_BASE_TP_BUFFER60      , 0x0000c1c1 }, /* TPBUFFER60   */
1081         { STB0899_OFF0_TP_BUFFER61      , STB0899_BASE_TP_BUFFER61      , 0x0000c1c1 }, /* TPBUFFER61   */
1082         { STB0899_OFF0_TP_BUFFER62      , STB0899_BASE_TP_BUFFER62      , 0x0000c1c1 }, /* TPBUFFER62   */
1083         { STB0899_OFF0_TP_BUFFER63      , STB0899_BASE_TP_BUFFER63      , 0x0000c1c0 }, /* TPBUFFER63   */
1084         { STB0899_OFF0_RESET_CNTRL      , STB0899_BASE_RESET_CNTRL      , 0x00000001 }, /* RESETCNTRL   */
1085         { STB0899_OFF0_ACM_ENABLE       , STB0899_BASE_ACM_ENABLE       , 0x00005654 }, /* ACMENABLE    */
1086         { STB0899_OFF0_DESCR_CNTRL      , STB0899_BASE_DESCR_CNTRL      , 0x00000000 }, /* DESCRCNTRL   */
1087         { STB0899_OFF0_CSM_CNTRL1       , STB0899_BASE_CSM_CNTRL1       , 0x00020019 }, /* CSMCNTRL1    */
1088         { STB0899_OFF0_CSM_CNTRL2       , STB0899_BASE_CSM_CNTRL2       , 0x004b3237 }, /* CSMCNTRL2    */
1089         { STB0899_OFF0_CSM_CNTRL3       , STB0899_BASE_CSM_CNTRL3       , 0x0003dd17 }, /* CSMCNTRL3    */
1090         { STB0899_OFF0_CSM_CNTRL4       , STB0899_BASE_CSM_CNTRL4       , 0x00008008 }, /* CSMCNTRL4    */
1091         { STB0899_OFF0_UWP_CNTRL1       , STB0899_BASE_UWP_CNTRL1       , 0x002a3106 }, /* UWPCNTRL1    */
1092         { STB0899_OFF0_UWP_CNTRL2       , STB0899_BASE_UWP_CNTRL2       , 0x0006140a }, /* UWPCNTRL2    */
1093         { STB0899_OFF0_UWP_STAT1        , STB0899_BASE_UWP_STAT1        , 0x00008000 }, /* UWPSTAT1     */
1094         { STB0899_OFF0_UWP_STAT2        , STB0899_BASE_UWP_STAT2        , 0x00000000 }, /* UWPSTAT2     */
1095         { STB0899_OFF0_DMD_STAT2        , STB0899_BASE_DMD_STAT2        , 0x00000000 }, /* DMDSTAT2     */
1096         { STB0899_OFF0_FREQ_ADJ_SCALE   , STB0899_BASE_FREQ_ADJ_SCALE   , 0x00000471 }, /* FREQADJSCALE */
1097         { STB0899_OFF0_UWP_CNTRL3       , STB0899_BASE_UWP_CNTRL3       , 0x017b0465 }, /* UWPCNTRL3    */
1098         { STB0899_OFF0_SYM_CLK_SEL      , STB0899_BASE_SYM_CLK_SEL      , 0x00000002 }, /* SYMCLKSEL    */
1099         { STB0899_OFF0_SOF_SRCH_TO      , STB0899_BASE_SOF_SRCH_TO      , 0x00196464 }, /* SOFSRCHTO    */
1100         { STB0899_OFF0_ACQ_CNTRL1       , STB0899_BASE_ACQ_CNTRL1       , 0x00000603 }, /* ACQCNTRL1    */
1101         { STB0899_OFF0_ACQ_CNTRL2       , STB0899_BASE_ACQ_CNTRL2       , 0x02046666 }, /* ACQCNTRL2    */
1102         { STB0899_OFF0_ACQ_CNTRL3       , STB0899_BASE_ACQ_CNTRL3       , 0x10046583 }, /* ACQCNTRL3    */
1103         { STB0899_OFF0_FE_SETTLE        , STB0899_BASE_FE_SETTLE        , 0x00010404 }, /* FESETTLE     */
1104         { STB0899_OFF0_AC_DWELL         , STB0899_BASE_AC_DWELL         , 0x0002aa8a }, /* ACDWELL      */
1105         { STB0899_OFF0_ACQUIRE_TRIG     , STB0899_BASE_ACQUIRE_TRIG     , 0x00000000 }, /* ACQUIRETRIG  */
1106         { STB0899_OFF0_LOCK_LOST        , STB0899_BASE_LOCK_LOST        , 0x00000001 }, /* LOCKLOST     */
1107         { STB0899_OFF0_ACQ_STAT1        , STB0899_BASE_ACQ_STAT1        , 0x00000500 }, /* ACQSTAT1     */
1108         { STB0899_OFF0_ACQ_TIMEOUT      , STB0899_BASE_ACQ_TIMEOUT      , 0x0028a0a0 }, /* ACQTIMEOUT   */
1109         { STB0899_OFF0_ACQ_TIME         , STB0899_BASE_ACQ_TIME         , 0x00000000 }, /* ACQTIME      */
1110         { STB0899_OFF0_FINAL_AGC_CNTRL  , STB0899_BASE_FINAL_AGC_CNTRL  , 0x00800c17 }, /* FINALAGCCNTRL*/
1111         { STB0899_OFF0_FINAL_AGC_GAIN   , STB0899_BASE_FINAL_AGC_GAIN   , 0x00000000 }, /* FINALAGCCGAIN*/
1112         { STB0899_OFF0_EQUALIZER_INIT   , STB0899_BASE_EQUALIZER_INIT   , 0x00000000 }, /* EQUILIZERINIT*/
1113         { STB0899_OFF0_EQ_CNTRL         , STB0899_BASE_EQ_CNTRL         , 0x00054802 }, /* EQCNTL       */
1114         { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */
1115         { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */
1116         { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */
1117         { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */
1118         { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */
1119         { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */
1120         { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */
1121         { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */
1122         { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */
1123         { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */
1124         { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/
1125         { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */
1126         { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */
1127         { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */
1128         { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */
1129         { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */
1130         { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */
1131         { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */
1132         { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */
1133         { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */
1134         { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */
1135         { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/
1136         { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */
1137         { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */
1138         { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */
1139         { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */
1140         { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */
1141         { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */
1142         { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */
1143         { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */
1144         { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */
1145         { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */
1146         { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N  , 0x00000000 }, /* EQICOEFFSOUT10*/
1147         { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */
1148         { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */
1149         { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */
1150         { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */
1151         { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */
1152         { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */
1153         { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */
1154         { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */
1155         { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */
1156         { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */
1157         { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/
1158         { 0xffff                        , 0xffffffff                    , 0xffffffff },
1159 };
1160
1161 static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
1162         { STB0899_DEMOD                 , 0x00 },
1163         { STB0899_RCOMPC                , 0xc9 },
1164         { STB0899_AGC1CN                , 0x41 },
1165         { STB0899_AGC1REF               , 0x08 },
1166         { STB0899_RTC                   , 0x7a },
1167         { STB0899_TMGCFG                , 0x4e },
1168         { STB0899_AGC2REF               , 0x33 },
1169         { STB0899_TLSR                  , 0x84 },
1170         { STB0899_CFD                   , 0xee },
1171         { STB0899_ACLC                  , 0x87 },
1172         { STB0899_BCLC                  , 0x94 },
1173         { STB0899_EQON                  , 0x41 },
1174         { STB0899_LDT                   , 0xdd },
1175         { STB0899_LDT2                  , 0xc9 },
1176         { STB0899_EQUALREF              , 0xb4 },
1177         { STB0899_TMGRAMP               , 0x10 },
1178         { STB0899_TMGTHD                , 0x30 },
1179         { STB0899_IDCCOMP               , 0xfb },
1180         { STB0899_QDCCOMP               , 0x03 },
1181         { STB0899_POWERI                , 0x3b },
1182         { STB0899_POWERQ                , 0x3d },
1183         { STB0899_RCOMP                 , 0x81 },
1184         { STB0899_AGCIQIN               , 0x80 },
1185         { STB0899_AGC2I1                , 0x04 },
1186         { STB0899_AGC2I2                , 0xf5 },
1187         { STB0899_TLIR                  , 0x25 },
1188         { STB0899_RTF                   , 0x80 },
1189         { STB0899_DSTATUS               , 0x00 },
1190         { STB0899_LDI                   , 0xca },
1191         { STB0899_CFRM                  , 0xf1 },
1192         { STB0899_CFRL                  , 0xf3 },
1193         { STB0899_NIRM                  , 0x2a },
1194         { STB0899_NIRL                  , 0x05 },
1195         { STB0899_ISYMB                 , 0x17 },
1196         { STB0899_QSYMB                 , 0xfa },
1197         { STB0899_SFRH                  , 0x2f },
1198         { STB0899_SFRM                  , 0x68 },
1199         { STB0899_SFRL                  , 0x40 },
1200         { STB0899_SFRUPH                , 0x2f },
1201         { STB0899_SFRUPM                , 0x68 },
1202         { STB0899_SFRUPL                , 0x40 },
1203         { STB0899_EQUAI1                , 0xfd },
1204         { STB0899_EQUAQ1                , 0x04 },
1205         { STB0899_EQUAI2                , 0x0f },
1206         { STB0899_EQUAQ2                , 0xff },
1207         { STB0899_EQUAI3                , 0xdf },
1208         { STB0899_EQUAQ3                , 0xfa },
1209         { STB0899_EQUAI4                , 0x37 },
1210         { STB0899_EQUAQ4                , 0x0d },
1211         { STB0899_EQUAI5                , 0xbd },
1212         { STB0899_EQUAQ5                , 0xf7 },
1213         { STB0899_DSTATUS2              , 0x00 },
1214         { STB0899_VSTATUS               , 0x00 },
1215         { STB0899_VERROR                , 0xff },
1216         { STB0899_IQSWAP                , 0x2a },
1217         { STB0899_ECNT1M                , 0x00 },
1218         { STB0899_ECNT1L                , 0x00 },
1219         { STB0899_ECNT2M                , 0x00 },
1220         { STB0899_ECNT2L                , 0x00 },
1221         { STB0899_ECNT3M                , 0x00 },
1222         { STB0899_ECNT3L                , 0x00 },
1223         { STB0899_FECAUTO1              , 0x06 },
1224         { STB0899_FECM                  , 0x01 },
1225         { STB0899_VTH12                 , 0xf0 },
1226         { STB0899_VTH23                 , 0xa0 },
1227         { STB0899_VTH34                 , 0x78 },
1228         { STB0899_VTH56                 , 0x4e },
1229         { STB0899_VTH67                 , 0x48 },
1230         { STB0899_VTH78                 , 0x38 },
1231         { STB0899_PRVIT                 , 0xff },
1232         { STB0899_VITSYNC               , 0x19 },
1233         { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1234         { STB0899_TSULC                 , 0x42 },
1235         { STB0899_RSLLC                 , 0x40 },
1236         { STB0899_TSLPL                 , 0x12 },
1237         { STB0899_TSCFGH                , 0x0c },
1238         { STB0899_TSCFGM                , 0x00 },
1239         { STB0899_TSCFGL                , 0x0c },
1240         { STB0899_TSOUT                 , 0x0d }, /* 0x0d for CAM */
1241         { STB0899_RSSYNCDEL             , 0x00 },
1242         { STB0899_TSINHDELH             , 0x02 },
1243         { STB0899_TSINHDELM             , 0x00 },
1244         { STB0899_TSINHDELL             , 0x00 },
1245         { STB0899_TSLLSTKM              , 0x00 },
1246         { STB0899_TSLLSTKL              , 0x00 },
1247         { STB0899_TSULSTKM              , 0x00 },
1248         { STB0899_TSULSTKL              , 0xab },
1249         { STB0899_PCKLENUL              , 0x00 },
1250         { STB0899_PCKLENLL              , 0xcc },
1251         { STB0899_RSPCKLEN              , 0xcc },
1252         { STB0899_TSSTATUS              , 0x80 },
1253         { STB0899_ERRCTRL1              , 0xb6 },
1254         { STB0899_ERRCTRL2              , 0x96 },
1255         { STB0899_ERRCTRL3              , 0x89 },
1256         { STB0899_DMONMSK1              , 0x27 },
1257         { STB0899_DMONMSK0              , 0x03 },
1258         { STB0899_DEMAPVIT              , 0x5c },
1259         { STB0899_PLPARM                , 0x1f },
1260         { STB0899_PDELCTRL              , 0x48 },
1261         { STB0899_PDELCTRL2             , 0x00 },
1262         { STB0899_BBHCTRL1              , 0x00 },
1263         { STB0899_BBHCTRL2              , 0x00 },
1264         { STB0899_HYSTTHRESH            , 0x77 },
1265         { STB0899_MATCSTM               , 0x00 },
1266         { STB0899_MATCSTL               , 0x00 },
1267         { STB0899_UPLCSTM               , 0x00 },
1268         { STB0899_UPLCSTL               , 0x00 },
1269         { STB0899_DFLCSTM               , 0x00 },
1270         { STB0899_DFLCSTL               , 0x00 },
1271         { STB0899_SYNCCST               , 0x00 },
1272         { STB0899_SYNCDCSTM             , 0x00 },
1273         { STB0899_SYNCDCSTL             , 0x00 },
1274         { STB0899_ISI_ENTRY             , 0x00 },
1275         { STB0899_ISI_BIT_EN            , 0x00 },
1276         { STB0899_MATSTRM               , 0x00 },
1277         { STB0899_MATSTRL               , 0x00 },
1278         { STB0899_UPLSTRM               , 0x00 },
1279         { STB0899_UPLSTRL               , 0x00 },
1280         { STB0899_DFLSTRM               , 0x00 },
1281         { STB0899_DFLSTRL               , 0x00 },
1282         { STB0899_SYNCSTR               , 0x00 },
1283         { STB0899_SYNCDSTRM             , 0x00 },
1284         { STB0899_SYNCDSTRL             , 0x00 },
1285         { STB0899_CFGPDELSTATUS1        , 0x10 },
1286         { STB0899_CFGPDELSTATUS2        , 0x00 },
1287         { STB0899_BBFERRORM             , 0x00 },
1288         { STB0899_BBFERRORL             , 0x00 },
1289         { STB0899_UPKTERRORM            , 0x00 },
1290         { STB0899_UPKTERRORL            , 0x00 },
1291         { 0xffff                        , 0xff },
1292 };
1293
1294 static const struct stb0899_s2_reg knc1_stb0899_s2_init_4[] = {
1295         { STB0899_OFF0_BLOCK_LNGTH      , STB0899_BASE_BLOCK_LNGTH      , 0x00000008 }, /* BLOCKLNGTH   */
1296         { STB0899_OFF0_ROW_STR          , STB0899_BASE_ROW_STR          , 0x000000b4 }, /* ROWSTR       */
1297         { STB0899_OFF0_BN_END_ADDR      , STB0899_BASE_BN_END_ADDR      , 0x000004b5 }, /* BNANDADDR    */
1298         { STB0899_OFF0_CN_END_ADDR      , STB0899_BASE_CN_END_ADDR      , 0x00000b4b }, /* CNANDADDR    */
1299         { STB0899_OFF0_INFO_LENGTH      , STB0899_BASE_INFO_LENGTH      , 0x00000078 }, /* INFOLENGTH   */
1300         { STB0899_OFF0_BOT_ADDR         , STB0899_BASE_BOT_ADDR         , 0x000001e0 }, /* BOT_ADDR     */
1301         { STB0899_OFF0_BCH_BLK_LN       , STB0899_BASE_BCH_BLK_LN       , 0x0000a8c0 }, /* BCHBLKLN     */
1302         { STB0899_OFF0_BCH_T            , STB0899_BASE_BCH_T            , 0x0000000c }, /* BCHT         */
1303         { STB0899_OFF0_CNFG_MODE        , STB0899_BASE_CNFG_MODE        , 0x00000001 }, /* CNFGMODE     */
1304         { STB0899_OFF0_LDPC_STAT        , STB0899_BASE_LDPC_STAT        , 0x0000000d }, /* LDPCSTAT     */
1305         { STB0899_OFF0_ITER_SCALE       , STB0899_BASE_ITER_SCALE       , 0x00000040 }, /* ITERSCALE    */
1306         { STB0899_OFF0_INPUT_MODE       , STB0899_BASE_INPUT_MODE       , 0x00000000 }, /* INPUTMODE    */
1307         { STB0899_OFF0_LDPCDECRST       , STB0899_BASE_LDPCDECRST       , 0x00000000 }, /* LDPCDECRST   */
1308         { STB0899_OFF0_CLK_PER_BYTE_RW  , STB0899_BASE_CLK_PER_BYTE_RW  , 0x00000008 }, /* CLKPERBYTE   */
1309         { STB0899_OFF0_BCH_ERRORS       , STB0899_BASE_BCH_ERRORS       , 0x00000000 }, /* BCHERRORS    */
1310         { STB0899_OFF0_LDPC_ERRORS      , STB0899_BASE_LDPC_ERRORS      , 0x00000000 }, /* LDPCERRORS   */
1311         { STB0899_OFF0_BCH_MODE         , STB0899_BASE_BCH_MODE         , 0x00000000 }, /* BCHMODE      */
1312         { STB0899_OFF0_ERR_ACC_PER      , STB0899_BASE_ERR_ACC_PER      , 0x00000008 }, /* ERRACCPER    */
1313         { STB0899_OFF0_BCH_ERR_ACC      , STB0899_BASE_BCH_ERR_ACC      , 0x00000000 }, /* BCHERRACC    */
1314         { STB0899_OFF0_FEC_TP_SEL       , STB0899_BASE_FEC_TP_SEL       , 0x00000000 }, /* FECTPSEL     */
1315         { 0xffff                        , 0xffffffff                    , 0xffffffff },
1316 };
1317
1318 static const struct stb0899_s1_reg knc1_stb0899_s1_init_5[] = {
1319         { STB0899_TSTCK         , 0x00 },
1320         { STB0899_TSTRES        , 0x00 },
1321         { STB0899_TSTOUT        , 0x00 },
1322         { STB0899_TSTIN         , 0x00 },
1323         { STB0899_TSTSYS        , 0x00 },
1324         { STB0899_TSTCHIP       , 0x00 },
1325         { STB0899_TSTFREE       , 0x00 },
1326         { STB0899_TSTI2C        , 0x00 },
1327         { STB0899_BITSPEEDM     , 0x00 },
1328         { STB0899_BITSPEEDL     , 0x00 },
1329         { STB0899_TBUSBIT       , 0x00 },
1330         { STB0899_TSTDIS        , 0x00 },
1331         { STB0899_TSTDISRX      , 0x00 },
1332         { STB0899_TSTJETON      , 0x00 },
1333         { STB0899_TSTDCADJ      , 0x00 },
1334         { STB0899_TSTAGC1       , 0x00 },
1335         { STB0899_TSTAGC1N      , 0x00 },
1336         { STB0899_TSTPOLYPH     , 0x00 },
1337         { STB0899_TSTR          , 0x00 },
1338         { STB0899_TSTAGC2       , 0x00 },
1339         { STB0899_TSTCTL1       , 0x00 },
1340         { STB0899_TSTCTL2       , 0x00 },
1341         { STB0899_TSTCTL3       , 0x00 },
1342         { STB0899_TSTDEMAP      , 0x00 },
1343         { STB0899_TSTDEMAP2     , 0x00 },
1344         { STB0899_TSTDEMMON     , 0x00 },
1345         { STB0899_TSTRATE       , 0x00 },
1346         { STB0899_TSTSELOUT     , 0x00 },
1347         { STB0899_TSYNC         , 0x00 },
1348         { STB0899_TSTERR        , 0x00 },
1349         { STB0899_TSTRAM1       , 0x00 },
1350         { STB0899_TSTVSELOUT    , 0x00 },
1351         { STB0899_TSTFORCEIN    , 0x00 },
1352         { STB0899_TSTRS1        , 0x00 },
1353         { STB0899_TSTRS2        , 0x00 },
1354         { STB0899_TSTRS3        , 0x00 },
1355         { STB0899_GHOSTREG      , 0x81 },
1356         { 0xffff                , 0xff },
1357 };
1358
1359 #define KNC1_DVBS2_ESNO_AVE                     3
1360 #define KNC1_DVBS2_ESNO_QUANT                   32
1361 #define KNC1_DVBS2_AVFRAMES_COARSE              10
1362 #define KNC1_DVBS2_AVFRAMES_FINE                20
1363 #define KNC1_DVBS2_MISS_THRESHOLD               6
1364 #define KNC1_DVBS2_UWP_THRESHOLD_ACQ            1125
1365 #define KNC1_DVBS2_UWP_THRESHOLD_TRACK          758
1366 #define KNC1_DVBS2_UWP_THRESHOLD_SOF            1350
1367 #define KNC1_DVBS2_SOF_SEARCH_TIMEOUT           1664100
1368
1369 #define KNC1_DVBS2_BTR_NCO_BITS                 28
1370 #define KNC1_DVBS2_BTR_GAIN_SHIFT_OFFSET        15
1371 #define KNC1_DVBS2_CRL_NCO_BITS                 30
1372 #define KNC1_DVBS2_LDPC_MAX_ITER                70
1373
1374 static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
1375 {
1376         struct dvb_frontend_ops *frontend_ops = NULL;
1377         struct dvb_tuner_ops    *tuner_ops = NULL;
1378         struct tuner_state      t_state;
1379         int err = 0;
1380
1381         if (&fe->ops)
1382                 frontend_ops = &fe->ops;
1383         if (&frontend_ops->tuner_ops)
1384                 tuner_ops = &frontend_ops->tuner_ops;
1385         if (tuner_ops->get_state) {
1386                 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
1387                         printk("%s: Invalid parameter\n", __func__);
1388                         return err;
1389                 }
1390                 *frequency = t_state.frequency;
1391                 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
1392         }
1393         return 0;
1394 }
1395
1396 static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency)
1397 {
1398         struct dvb_frontend_ops *frontend_ops = NULL;
1399         struct dvb_tuner_ops    *tuner_ops = NULL;
1400         struct tuner_state      t_state;
1401         int err = 0;
1402
1403         t_state.frequency = frequency;
1404         if (&fe->ops)
1405                 frontend_ops = &fe->ops;
1406         if (&frontend_ops->tuner_ops)
1407                 tuner_ops = &frontend_ops->tuner_ops;
1408         if (tuner_ops->set_state) {
1409                 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
1410                         printk("%s: Invalid parameter\n", __func__);
1411                         return err;
1412                 }
1413         }
1414         printk("%s: Frequency=%d\n", __func__, t_state.frequency);
1415         return 0;
1416 }
1417
1418 static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
1419 {
1420         struct dvb_frontend_ops *frontend_ops = &fe->ops;
1421         struct dvb_tuner_ops    *tuner_ops = &frontend_ops->tuner_ops;
1422         struct tuner_state      t_state;
1423         int err = 0;
1424
1425         if (&fe->ops)
1426                 frontend_ops = &fe->ops;
1427         if (&frontend_ops->tuner_ops)
1428                 tuner_ops = &frontend_ops->tuner_ops;
1429         if (tuner_ops->get_state) {
1430                 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
1431                         printk("%s: Invalid parameter\n", __func__);
1432                         return err;
1433                 }
1434                 *bandwidth = t_state.bandwidth;
1435         }
1436         printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
1437         return 0;
1438 }
1439
1440 /* STB0899 demodulator config for the KNC1 and clones */
1441 static struct stb0899_config knc1_dvbs2_config = {
1442         .init_dev               = knc1_stb0899_s1_init_1,
1443         .init_s2_demod          = knc1_stb0899_s2_init_2,
1444         .init_s1_demod          = knc1_stb0899_s1_init_3,
1445         .init_s2_fec            = knc1_stb0899_s2_init_4,
1446         .init_tst               = knc1_stb0899_s1_init_5,
1447
1448         .demod_address          = 0x68,
1449 //      .ts_output_mode         = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL      */
1450         .block_sync_mode        = STB0899_SYNC_FORCED,  /* DSS, SYNC_FORCED/UNSYNCED    */
1451 //      .ts_pfbit_toggle        = STB0899_MPEG_NORMAL,  /* DirecTV, MPEG toggling seq   */
1452
1453         .xtal_freq              = 27000000,
1454         .inversion              = IQ_SWAP_OFF, /* 1 */
1455
1456         .esno_ave               = KNC1_DVBS2_ESNO_AVE,
1457         .esno_quant             = KNC1_DVBS2_ESNO_QUANT,
1458         .avframes_coarse        = KNC1_DVBS2_AVFRAMES_COARSE,
1459         .avframes_fine          = KNC1_DVBS2_AVFRAMES_FINE,
1460         .miss_threshold         = KNC1_DVBS2_MISS_THRESHOLD,
1461         .uwp_threshold_acq      = KNC1_DVBS2_UWP_THRESHOLD_ACQ,
1462         .uwp_threshold_track    = KNC1_DVBS2_UWP_THRESHOLD_TRACK,
1463         .uwp_threshold_sof      = KNC1_DVBS2_UWP_THRESHOLD_SOF,
1464         .sof_search_timeout     = KNC1_DVBS2_SOF_SEARCH_TIMEOUT,
1465
1466         .btr_nco_bits           = KNC1_DVBS2_BTR_NCO_BITS,
1467         .btr_gain_shift_offset  = KNC1_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1468         .crl_nco_bits           = KNC1_DVBS2_CRL_NCO_BITS,
1469         .ldpc_max_iter          = KNC1_DVBS2_LDPC_MAX_ITER,
1470
1471         .tuner_get_frequency    = tda8261_get_frequency,
1472         .tuner_set_frequency    = tda8261_set_frequency,
1473         .tuner_set_bandwidth    = NULL,
1474         .tuner_get_bandwidth    = tda8261_get_bandwidth,
1475         .tuner_set_rfsiggain    = NULL,
1476 };
1477
1478 /*
1479  * SD1878/SHA tuner config
1480  * 1F, Single I/P, Horizontal mount, High Sensitivity
1481  */
1482 static const struct tda8261_config sd1878c_config = {
1483 //      .name           = "SD1878/SHA",
1484         .addr           = 0x60,
1485         .step_size      = TDA8261_STEP_1000 /* kHz */
1486 };
1487
1488 static u8 read_pwm(struct budget_av *budget_av)
1489 {
1490         u8 b = 0xff;
1491         u8 pwm;
1492         struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
1493         {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
1494         };
1495
1496         if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
1497             || (pwm == 0xff))
1498                 pwm = 0x48;
1499
1500         return pwm;
1501 }
1502
1503 #define SUBID_DVBS_KNC1                 0x0010
1504 #define SUBID_DVBS_KNC1_PLUS            0x0011
1505 #define SUBID_DVBS_TYPHOON              0x4f56
1506 #define SUBID_DVBS_CINERGY1200          0x1154
1507 #define SUBID_DVBS_CYNERGY1200N         0x1155
1508 #define SUBID_DVBS_TV_STAR              0x0014
1509 #define SUBID_DVBS_TV_STAR_PLUS_X4      0x0015
1510 #define SUBID_DVBS_TV_STAR_CI           0x0016
1511 #define SUBID_DVBS2_KNC1                0x0018
1512 #define SUBID_DVBS2_KNC1_OEM            0x0019
1513 #define SUBID_DVBS_EASYWATCH_1          0x001a
1514 #define SUBID_DVBS_EASYWATCH_2          0x001b
1515 #define SUBID_DVBS2_EASYWATCH           0x001d
1516 #define SUBID_DVBS_EASYWATCH            0x001e
1517
1518 #define SUBID_DVBC_EASYWATCH            0x002a
1519 #define SUBID_DVBC_EASYWATCH_MK3        0x002c
1520 #define SUBID_DVBC_KNC1                 0x0020
1521 #define SUBID_DVBC_KNC1_PLUS            0x0021
1522 #define SUBID_DVBC_KNC1_MK3             0x0022
1523 #define SUBID_DVBC_KNC1_PLUS_MK3        0x0023
1524 #define SUBID_DVBC_CINERGY1200          0x1156
1525 #define SUBID_DVBC_CINERGY1200_MK3      0x1176
1526
1527 #define SUBID_DVBT_EASYWATCH            0x003a
1528 #define SUBID_DVBT_KNC1_PLUS            0x0031
1529 #define SUBID_DVBT_KNC1                 0x0030
1530 #define SUBID_DVBT_CINERGY1200          0x1157
1531
1532 static void frontend_init(struct budget_av *budget_av)
1533 {
1534         struct saa7146_dev * saa = budget_av->budget.dev;
1535         struct dvb_frontend * fe = NULL;
1536
1537         /* Enable / PowerON Frontend */
1538         saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
1539
1540         /* Wait for PowerON */
1541         msleep(100);
1542
1543         /* additional setup necessary for the PLUS cards */
1544         switch (saa->pci->subsystem_device) {
1545                 case SUBID_DVBS_KNC1_PLUS:
1546                 case SUBID_DVBC_KNC1_PLUS:
1547                 case SUBID_DVBT_KNC1_PLUS:
1548                 case SUBID_DVBC_EASYWATCH:
1549                 case SUBID_DVBC_KNC1_PLUS_MK3:
1550                 case SUBID_DVBS2_KNC1:
1551                 case SUBID_DVBS2_KNC1_OEM:
1552                 case SUBID_DVBS2_EASYWATCH:
1553                         saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
1554                         break;
1555         }
1556
1557         switch (saa->pci->subsystem_device) {
1558
1559         case SUBID_DVBS_KNC1:
1560                 /*
1561                  * maybe that setting is needed for other dvb-s cards as well,
1562                  * but so far it has been only confirmed for this type
1563                  */
1564                 budget_av->reinitialise_demod = 1;
1565                 /* fall through */
1566         case SUBID_DVBS_KNC1_PLUS:
1567         case SUBID_DVBS_EASYWATCH_1:
1568                 if (saa->pci->subsystem_vendor == 0x1894) {
1569                         fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
1570                                              &budget_av->budget.i2c_adap);
1571                         if (fe) {
1572                                 dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
1573                         }
1574                 } else {
1575                         fe = dvb_attach(stv0299_attach, &typhoon_config,
1576                                              &budget_av->budget.i2c_adap);
1577                         if (fe) {
1578                                 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1579                         }
1580                 }
1581                 break;
1582
1583         case SUBID_DVBS_TV_STAR:
1584         case SUBID_DVBS_TV_STAR_PLUS_X4:
1585         case SUBID_DVBS_TV_STAR_CI:
1586         case SUBID_DVBS_CYNERGY1200N:
1587         case SUBID_DVBS_EASYWATCH:
1588         case SUBID_DVBS_EASYWATCH_2:
1589                 fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
1590                                 &budget_av->budget.i2c_adap);
1591                 if (fe) {
1592                         dvb_attach(dvb_pll_attach, fe, 0x60,
1593                                    &budget_av->budget.i2c_adap,
1594                                    DVB_PLL_PHILIPS_SD1878_TDA8261);
1595                 }
1596                 break;
1597
1598         case SUBID_DVBS_TYPHOON:
1599                 fe = dvb_attach(stv0299_attach, &typhoon_config,
1600                                     &budget_av->budget.i2c_adap);
1601                 if (fe) {
1602                         fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1603                 }
1604                 break;
1605         case SUBID_DVBS2_KNC1:
1606         case SUBID_DVBS2_KNC1_OEM:
1607         case SUBID_DVBS2_EASYWATCH:
1608                 budget_av->reinitialise_demod = 1;
1609                 if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
1610                         dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
1611
1612                 break;
1613         case SUBID_DVBS_CINERGY1200:
1614                 fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
1615                                     &budget_av->budget.i2c_adap);
1616                 if (fe) {
1617                         fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1618                 }
1619                 break;
1620
1621         case SUBID_DVBC_KNC1:
1622         case SUBID_DVBC_KNC1_PLUS:
1623         case SUBID_DVBC_CINERGY1200:
1624         case SUBID_DVBC_EASYWATCH:
1625                 budget_av->reinitialise_demod = 1;
1626                 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1627                 fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
1628                                      &budget_av->budget.i2c_adap,
1629                                      read_pwm(budget_av));
1630                 if (fe == NULL)
1631                         fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
1632                                              &budget_av->budget.i2c_adap,
1633                                              read_pwm(budget_av));
1634                 if (fe) {
1635                         fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1636                 }
1637                 break;
1638
1639         case SUBID_DVBC_EASYWATCH_MK3:
1640         case SUBID_DVBC_CINERGY1200_MK3:
1641         case SUBID_DVBC_KNC1_MK3:
1642         case SUBID_DVBC_KNC1_PLUS_MK3:
1643                 budget_av->reinitialise_demod = 1;
1644                 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1645                 fe = dvb_attach(tda10023_attach,
1646                         &philips_cu1216_tda10023_config,
1647                         &budget_av->budget.i2c_adap,
1648                         read_pwm(budget_av));
1649                 if (fe) {
1650                         fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1651                 }
1652                 break;
1653
1654         case SUBID_DVBT_EASYWATCH:
1655         case SUBID_DVBT_KNC1:
1656         case SUBID_DVBT_KNC1_PLUS:
1657         case SUBID_DVBT_CINERGY1200:
1658                 budget_av->reinitialise_demod = 1;
1659                 fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
1660                                      &budget_av->budget.i2c_adap);
1661                 if (fe) {
1662                         fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1663                         fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
1664                 }
1665                 break;
1666         }
1667
1668         if (fe == NULL) {
1669                 printk(KERN_ERR "budget-av: A frontend driver was not found "
1670                                 "for device [%04x:%04x] subsystem [%04x:%04x]\n",
1671                        saa->pci->vendor,
1672                        saa->pci->device,
1673                        saa->pci->subsystem_vendor,
1674                        saa->pci->subsystem_device);
1675                 return;
1676         }
1677
1678         budget_av->budget.dvb_frontend = fe;
1679
1680         if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1681                                   budget_av->budget.dvb_frontend)) {
1682                 printk(KERN_ERR "budget-av: Frontend registration failed!\n");
1683                 dvb_frontend_detach(budget_av->budget.dvb_frontend);
1684                 budget_av->budget.dvb_frontend = NULL;
1685         }
1686 }
1687
1688
1689 static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1690 {
1691         struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1692
1693         dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1694
1695         if (*isr & MASK_10)
1696                 ttpci_budget_irq10_handler(dev, isr);
1697 }
1698
1699 static int budget_av_detach(struct saa7146_dev *dev)
1700 {
1701         struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1702         int err;
1703
1704         dprintk(2, "dev: %p\n", dev);
1705
1706         if (1 == budget_av->has_saa7113) {
1707                 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
1708
1709                 msleep(200);
1710
1711                 saa7146_unregister_device(&budget_av->vd, dev);
1712
1713                 saa7146_vv_release(dev);
1714         }
1715
1716         if (budget_av->budget.ci_present)
1717                 ciintf_deinit(budget_av);
1718
1719         if (budget_av->budget.dvb_frontend != NULL) {
1720                 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
1721                 dvb_frontend_detach(budget_av->budget.dvb_frontend);
1722         }
1723         err = ttpci_budget_deinit(&budget_av->budget);
1724
1725         kfree(budget_av);
1726
1727         return err;
1728 }
1729
1730 static struct saa7146_ext_vv vv_data;
1731
1732 static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1733 {
1734         struct budget_av *budget_av;
1735         u8 *mac;
1736         int err;
1737
1738         dprintk(2, "dev: %p\n", dev);
1739
1740         if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
1741                 return -ENOMEM;
1742
1743         budget_av->has_saa7113 = 0;
1744         budget_av->budget.ci_present = 0;
1745
1746         dev->ext_priv = budget_av;
1747
1748         err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
1749                                 adapter_nr);
1750         if (err) {
1751                 kfree(budget_av);
1752                 return err;
1753         }
1754
1755         /* knc1 initialization */
1756         saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1757         saa7146_write(dev, DD1_INIT, 0x07000600);
1758         saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
1759
1760         if (saa7113_init(budget_av) == 0) {
1761                 budget_av->has_saa7113 = 1;
1762
1763                 if (0 != saa7146_vv_init(dev, &vv_data)) {
1764                         /* fixme: proper cleanup here */
1765                         ERR(("cannot init vv subsystem.\n"));
1766                         return err;
1767                 }
1768
1769                 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1770                         /* fixme: proper cleanup here */
1771                         ERR(("cannot register capture v4l2 device.\n"));
1772                         saa7146_vv_release(dev);
1773                         return err;
1774                 }
1775
1776                 /* beware: this modifies dev->vv ... */
1777                 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
1778                                                 SAA7146_HPS_SYNC_PORT_A);
1779
1780                 saa7113_setinput(budget_av, 0);
1781         }
1782
1783         /* fixme: find some sane values here... */
1784         saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1785
1786         mac = budget_av->budget.dvb_adapter.proposed_mac;
1787         if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
1788                 printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n",
1789                        budget_av->budget.dvb_adapter.num);
1790                 memset(mac, 0, 6);
1791         } else {
1792                 printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
1793                        budget_av->budget.dvb_adapter.num,
1794                        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1795         }
1796
1797         budget_av->budget.dvb_adapter.priv = budget_av;
1798         frontend_init(budget_av);
1799         ciintf_init(budget_av);
1800
1801         ttpci_budget_init_hooks(&budget_av->budget);
1802
1803         return 0;
1804 }
1805
1806 #define KNC1_INPUTS 2
1807 static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1808         {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1809         {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1810 };
1811
1812 static struct saa7146_extension_ioctls ioctls[] = {
1813         {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
1814         {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
1815         {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
1816         {0, 0}
1817 };
1818
1819 static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
1820 {
1821         struct saa7146_dev *dev = fh->dev;
1822         struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1823
1824         switch (cmd) {
1825         case VIDIOC_ENUMINPUT:{
1826                 struct v4l2_input *i = arg;
1827
1828                 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
1829                 if (i->index < 0 || i->index >= KNC1_INPUTS) {
1830                         return -EINVAL;
1831                 }
1832                 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1833                 return 0;
1834         }
1835         case VIDIOC_G_INPUT:{
1836                 int *input = (int *) arg;
1837
1838                 *input = budget_av->cur_input;
1839
1840                 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
1841                 return 0;
1842         }
1843         case VIDIOC_S_INPUT:{
1844                 int input = *(int *) arg;
1845                 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
1846                 return saa7113_setinput(budget_av, input);
1847         }
1848         default:
1849                 return -ENOIOCTLCMD;
1850         }
1851         return 0;
1852 }
1853
1854 static struct saa7146_standard standard[] = {
1855         {.name = "PAL",.id = V4L2_STD_PAL,
1856          .v_offset = 0x17,.v_field = 288,
1857          .h_offset = 0x14,.h_pixels = 680,
1858          .v_max_out = 576,.h_max_out = 768 },
1859
1860         {.name = "NTSC",.id = V4L2_STD_NTSC,
1861          .v_offset = 0x16,.v_field = 240,
1862          .h_offset = 0x06,.h_pixels = 708,
1863          .v_max_out = 480,.h_max_out = 640, },
1864 };
1865
1866 static struct saa7146_ext_vv vv_data = {
1867         .inputs = 2,
1868         .capabilities = 0,      // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
1869         .flags = 0,
1870         .stds = &standard[0],
1871         .num_stds = ARRAY_SIZE(standard),
1872         .ioctls = &ioctls[0],
1873         .ioctl = av_ioctl,
1874 };
1875
1876 static struct saa7146_extension budget_extension;
1877
1878 MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
1879 MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
1880 MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
1881 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1882 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
1883 MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
1884 MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
1885 MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
1886 MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
1887 MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
1888 MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
1889 MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
1890 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
1891 MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
1892 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
1893 MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
1894 MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
1895 MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
1896 MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1897 MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1898 MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
1899 MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
1900 MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1901
1902 static struct pci_device_id pci_tbl[] = {
1903         MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
1904         MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
1905         MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
1906         MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
1907         MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
1908         MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
1909         MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
1910         MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
1911         MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
1912         MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
1913         MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
1914         MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1915         MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1916         MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
1917         MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
1918         MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
1919         MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
1920         MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1921         MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
1922         MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
1923         MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
1924         MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
1925         MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
1926         MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
1927         MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
1928         MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
1929         MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
1930         MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1931         {
1932          .vendor = 0,
1933         }
1934 };
1935
1936 MODULE_DEVICE_TABLE(pci, pci_tbl);
1937
1938 static struct saa7146_extension budget_extension = {
1939         .name = "budget_av",
1940         .flags = SAA7146_USE_I2C_IRQ,
1941
1942         .pci_tbl = pci_tbl,
1943
1944         .module = THIS_MODULE,
1945         .attach = budget_av_attach,
1946         .detach = budget_av_detach,
1947
1948         .irq_mask = MASK_10,
1949         .irq_func = budget_av_irq,
1950 };
1951
1952 static int __init budget_av_init(void)
1953 {
1954         return saa7146_register_extension(&budget_extension);
1955 }
1956
1957 static void __exit budget_av_exit(void)
1958 {
1959         saa7146_unregister_extension(&budget_extension);
1960 }
1961
1962 module_init(budget_av_init);
1963 module_exit(budget_av_exit);
1964
1965 MODULE_LICENSE("GPL");
1966 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1967 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1968                    "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");