e1bbab3dd6bab0886da33fc0f8899a055709c4c4
[safe/jmp/linux-2.6] / drivers / media / dvb / ttpci / budget-ci.c
1 /*
2  * budget-ci.c: driver for the SAA7146 based Budget DVB cards
3  *
4  * Compiled from various sources by Michael Hunold <michael@mihu.de>
5  *
6  *     msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
7  *     partially based on the Siemens DVB driver by Ralph+Marcus Metzler
8  *
9  * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27  *
28  *
29  * the project's page is at http://www.linuxtv.org/dvb/
30  */
31
32 #include <linux/module.h>
33 #include <linux/errno.h>
34 #include <linux/slab.h>
35 #include <linux/interrupt.h>
36 #include <linux/input.h>
37 #include <linux/spinlock.h>
38 #include <media/ir-common.h>
39
40 #include "budget.h"
41
42 #include "dvb_ca_en50221.h"
43 #include "stv0299.h"
44 #include "stv0297.h"
45 #include "tda1004x.h"
46 #include "stb0899_drv.h"
47 #include "stb0899_reg.h"
48 #include "stb6100.h"
49 #include "lnbp21.h"
50 #include "bsbe1.h"
51 #include "bsru6.h"
52 #include "tda1002x.h"
53 #include "tda827x.h"
54
55 /*
56  * Regarding DEBIADDR_IR:
57  * Some CI modules hang if random addresses are read.
58  * Using address 0x4000 for the IR read means that we
59  * use the same address as for CI version, which should
60  * be a safe default.
61  */
62 #define DEBIADDR_IR             0x4000
63 #define DEBIADDR_CICONTROL      0x0000
64 #define DEBIADDR_CIVERSION      0x4000
65 #define DEBIADDR_IO             0x1000
66 #define DEBIADDR_ATTR           0x3000
67
68 #define CICONTROL_RESET         0x01
69 #define CICONTROL_ENABLETS      0x02
70 #define CICONTROL_CAMDETECT     0x08
71
72 #define DEBICICTL               0x00420000
73 #define DEBICICAM               0x02420000
74
75 #define SLOTSTATUS_NONE         1
76 #define SLOTSTATUS_PRESENT      2
77 #define SLOTSTATUS_RESET        4
78 #define SLOTSTATUS_READY        8
79 #define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
80
81 /*
82  * Milliseconds during which a key is regarded as pressed.
83  * If an identical command arrives within this time, the timer will start over.
84  */
85 #define IR_KEYPRESS_TIMEOUT     250
86
87 /* RC5 device wildcard */
88 #define IR_DEVICE_ANY           255
89
90 static int rc5_device = -1;
91 module_param(rc5_device, int, 0644);
92 MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
93
94 static int ir_debug;
95 module_param(ir_debug, int, 0644);
96 MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
97
98 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
99
100 struct budget_ci_ir {
101         struct input_dev *dev;
102         struct tasklet_struct msp430_irq_tasklet;
103         struct timer_list timer_keyup;
104         char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
105         char phys[32];
106         struct ir_input_state state;
107         int rc5_device;
108         u32 last_raw;
109         u32 ir_key;
110         bool have_command;
111 };
112
113 struct budget_ci {
114         struct budget budget;
115         struct tasklet_struct ciintf_irq_tasklet;
116         int slot_status;
117         int ci_irq;
118         struct dvb_ca_en50221 ca;
119         struct budget_ci_ir ir;
120         u8 tuner_pll_address; /* used for philips_tdm1316l configs */
121 };
122
123 static void msp430_ir_keyup(unsigned long data)
124 {
125         struct budget_ci_ir *ir = (struct budget_ci_ir *) data;
126         ir_input_nokey(ir->dev, &ir->state);
127 }
128
129 static void msp430_ir_interrupt(unsigned long data)
130 {
131         struct budget_ci *budget_ci = (struct budget_ci *) data;
132         struct input_dev *dev = budget_ci->ir.dev;
133         u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
134         u32 raw;
135
136         /*
137          * The msp430 chip can generate two different bytes, command and device
138          *
139          * type1: X1CCCCCC, C = command bits (0 - 63)
140          * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
141          *
142          * Each signal from the remote control can generate one or more command
143          * bytes and one or more device bytes. For the repeated bytes, the
144          * highest bit (X) is set. The first command byte is always generated
145          * before the first device byte. Other than that, no specific order
146          * seems to apply. To make life interesting, bytes can also be lost.
147          *
148          * Only when we have a command and device byte, a keypress is
149          * generated.
150          */
151
152         if (ir_debug)
153                 printk("budget_ci: received byte 0x%02x\n", command);
154
155         /* Remove repeat bit, we use every command */
156         command = command & 0x7f;
157
158         /* Is this a RC5 command byte? */
159         if (command & 0x40) {
160                 budget_ci->ir.have_command = true;
161                 budget_ci->ir.ir_key = command & 0x3f;
162                 return;
163         }
164
165         /* It's a RC5 device byte */
166         if (!budget_ci->ir.have_command)
167                 return;
168         budget_ci->ir.have_command = false;
169
170         if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
171             budget_ci->ir.rc5_device != (command & 0x1f))
172                 return;
173
174         /* Is this a repeated key sequence? (same device, command, toggle) */
175         raw = budget_ci->ir.ir_key | (command << 8);
176         if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) {
177                 ir_input_nokey(dev, &budget_ci->ir.state);
178                 ir_input_keydown(dev, &budget_ci->ir.state,
179                                  budget_ci->ir.ir_key, raw);
180                 budget_ci->ir.last_raw = raw;
181         }
182
183         mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT));
184 }
185
186 static int msp430_ir_init(struct budget_ci *budget_ci)
187 {
188         struct saa7146_dev *saa = budget_ci->budget.dev;
189         struct input_dev *input_dev = budget_ci->ir.dev;
190         int error;
191
192         budget_ci->ir.dev = input_dev = input_allocate_device();
193         if (!input_dev) {
194                 printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
195                 error = -ENOMEM;
196                 goto out1;
197         }
198
199         snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
200                  "Budget-CI dvb ir receiver %s", saa->name);
201         snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
202                  "pci-%s/ir0", pci_name(saa->pci));
203
204         input_dev->name = budget_ci->ir.name;
205
206         input_dev->phys = budget_ci->ir.phys;
207         input_dev->id.bustype = BUS_PCI;
208         input_dev->id.version = 1;
209         if (saa->pci->subsystem_vendor) {
210                 input_dev->id.vendor = saa->pci->subsystem_vendor;
211                 input_dev->id.product = saa->pci->subsystem_device;
212         } else {
213                 input_dev->id.vendor = saa->pci->vendor;
214                 input_dev->id.product = saa->pci->device;
215         }
216         input_dev->dev.parent = &saa->pci->dev;
217
218         /* Select keymap and address */
219         switch (budget_ci->budget.dev->pci->subsystem_device) {
220         case 0x100c:
221         case 0x100f:
222         case 0x1011:
223         case 0x1012:
224                 /* The hauppauge keymap is a superset of these remotes */
225                 ir_input_init(input_dev, &budget_ci->ir.state,
226                               IR_TYPE_RC5, ir_codes_hauppauge_new);
227
228                 if (rc5_device < 0)
229                         budget_ci->ir.rc5_device = 0x1f;
230                 else
231                         budget_ci->ir.rc5_device = rc5_device;
232                 break;
233         case 0x1010:
234         case 0x1017:
235         case 0x101a:
236                 /* for the Technotrend 1500 bundled remote */
237                 ir_input_init(input_dev, &budget_ci->ir.state,
238                               IR_TYPE_RC5, ir_codes_tt_1500);
239
240                 if (rc5_device < 0)
241                         budget_ci->ir.rc5_device = IR_DEVICE_ANY;
242                 else
243                         budget_ci->ir.rc5_device = rc5_device;
244                 break;
245         default:
246                 /* unknown remote */
247                 ir_input_init(input_dev, &budget_ci->ir.state,
248                               IR_TYPE_RC5, ir_codes_budget_ci_old);
249
250                 if (rc5_device < 0)
251                         budget_ci->ir.rc5_device = IR_DEVICE_ANY;
252                 else
253                         budget_ci->ir.rc5_device = rc5_device;
254                 break;
255         }
256
257         /* initialise the key-up timeout handler */
258         init_timer(&budget_ci->ir.timer_keyup);
259         budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
260         budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
261         budget_ci->ir.last_raw = 0xffff; /* An impossible value */
262         error = input_register_device(input_dev);
263         if (error) {
264                 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
265                 goto out2;
266         }
267
268         /* note: these must be after input_register_device */
269         input_dev->rep[REP_DELAY] = 400;
270         input_dev->rep[REP_PERIOD] = 250;
271
272         tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
273                      (unsigned long) budget_ci);
274
275         SAA7146_IER_ENABLE(saa, MASK_06);
276         saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
277
278         return 0;
279
280 out2:
281         input_free_device(input_dev);
282 out1:
283         return error;
284 }
285
286 static void msp430_ir_deinit(struct budget_ci *budget_ci)
287 {
288         struct saa7146_dev *saa = budget_ci->budget.dev;
289         struct input_dev *dev = budget_ci->ir.dev;
290
291         SAA7146_IER_DISABLE(saa, MASK_06);
292         saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
293         tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
294
295         del_timer_sync(&dev->timer);
296         ir_input_nokey(dev, &budget_ci->ir.state);
297
298         input_unregister_device(dev);
299 }
300
301 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
302 {
303         struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
304
305         if (slot != 0)
306                 return -EINVAL;
307
308         return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
309                                      DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
310 }
311
312 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
313 {
314         struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
315
316         if (slot != 0)
317                 return -EINVAL;
318
319         return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
320                                       DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
321 }
322
323 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
324 {
325         struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
326
327         if (slot != 0)
328                 return -EINVAL;
329
330         return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
331                                      DEBIADDR_IO | (address & 3), 1, 1, 0);
332 }
333
334 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
335 {
336         struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
337
338         if (slot != 0)
339                 return -EINVAL;
340
341         return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
342                                       DEBIADDR_IO | (address & 3), 1, value, 1, 0);
343 }
344
345 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
346 {
347         struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
348         struct saa7146_dev *saa = budget_ci->budget.dev;
349
350         if (slot != 0)
351                 return -EINVAL;
352
353         if (budget_ci->ci_irq) {
354                 // trigger on RISING edge during reset so we know when READY is re-asserted
355                 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
356         }
357         budget_ci->slot_status = SLOTSTATUS_RESET;
358         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
359         msleep(1);
360         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
361                                CICONTROL_RESET, 1, 0);
362
363         saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
364         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
365         return 0;
366 }
367
368 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
369 {
370         struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
371         struct saa7146_dev *saa = budget_ci->budget.dev;
372
373         if (slot != 0)
374                 return -EINVAL;
375
376         saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
377         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
378         return 0;
379 }
380
381 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
382 {
383         struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
384         struct saa7146_dev *saa = budget_ci->budget.dev;
385         int tmp;
386
387         if (slot != 0)
388                 return -EINVAL;
389
390         saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
391
392         tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
393         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
394                                tmp | CICONTROL_ENABLETS, 1, 0);
395
396         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
397         return 0;
398 }
399
400 static void ciintf_interrupt(unsigned long data)
401 {
402         struct budget_ci *budget_ci = (struct budget_ci *) data;
403         struct saa7146_dev *saa = budget_ci->budget.dev;
404         unsigned int flags;
405
406         // ensure we don't get spurious IRQs during initialisation
407         if (!budget_ci->budget.ci_present)
408                 return;
409
410         // read the CAM status
411         flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
412         if (flags & CICONTROL_CAMDETECT) {
413
414                 // GPIO should be set to trigger on falling edge if a CAM is present
415                 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
416
417                 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
418                         // CAM insertion IRQ
419                         budget_ci->slot_status = SLOTSTATUS_PRESENT;
420                         dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
421                                                      DVB_CA_EN50221_CAMCHANGE_INSERTED);
422
423                 } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
424                         // CAM ready (reset completed)
425                         budget_ci->slot_status = SLOTSTATUS_READY;
426                         dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
427
428                 } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
429                         // FR/DA IRQ
430                         dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
431                 }
432         } else {
433
434                 // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
435                 // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
436                 // the CAM might not actually be ready yet.
437                 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
438
439                 // generate a CAM removal IRQ if we haven't already
440                 if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
441                         // CAM removal IRQ
442                         budget_ci->slot_status = SLOTSTATUS_NONE;
443                         dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
444                                                      DVB_CA_EN50221_CAMCHANGE_REMOVED);
445                 }
446         }
447 }
448
449 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
450 {
451         struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
452         unsigned int flags;
453
454         // ensure we don't get spurious IRQs during initialisation
455         if (!budget_ci->budget.ci_present)
456                 return -EINVAL;
457
458         // read the CAM status
459         flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
460         if (flags & CICONTROL_CAMDETECT) {
461                 // mark it as present if it wasn't before
462                 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
463                         budget_ci->slot_status = SLOTSTATUS_PRESENT;
464                 }
465
466                 // during a RESET, we check if we can read from IO memory to see when CAM is ready
467                 if (budget_ci->slot_status & SLOTSTATUS_RESET) {
468                         if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
469                                 budget_ci->slot_status = SLOTSTATUS_READY;
470                         }
471                 }
472         } else {
473                 budget_ci->slot_status = SLOTSTATUS_NONE;
474         }
475
476         if (budget_ci->slot_status != SLOTSTATUS_NONE) {
477                 if (budget_ci->slot_status & SLOTSTATUS_READY) {
478                         return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
479                 }
480                 return DVB_CA_EN50221_POLL_CAM_PRESENT;
481         }
482
483         return 0;
484 }
485
486 static int ciintf_init(struct budget_ci *budget_ci)
487 {
488         struct saa7146_dev *saa = budget_ci->budget.dev;
489         int flags;
490         int result;
491         int ci_version;
492         int ca_flags;
493
494         memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
495
496         // enable DEBI pins
497         saa7146_write(saa, MC1, MASK_27 | MASK_11);
498
499         // test if it is there
500         ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
501         if ((ci_version & 0xa0) != 0xa0) {
502                 result = -ENODEV;
503                 goto error;
504         }
505
506         // determine whether a CAM is present or not
507         flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
508         budget_ci->slot_status = SLOTSTATUS_NONE;
509         if (flags & CICONTROL_CAMDETECT)
510                 budget_ci->slot_status = SLOTSTATUS_PRESENT;
511
512         // version 0xa2 of the CI firmware doesn't generate interrupts
513         if (ci_version == 0xa2) {
514                 ca_flags = 0;
515                 budget_ci->ci_irq = 0;
516         } else {
517                 ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
518                                 DVB_CA_EN50221_FLAG_IRQ_FR |
519                                 DVB_CA_EN50221_FLAG_IRQ_DA;
520                 budget_ci->ci_irq = 1;
521         }
522
523         // register CI interface
524         budget_ci->ca.owner = THIS_MODULE;
525         budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
526         budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
527         budget_ci->ca.read_cam_control = ciintf_read_cam_control;
528         budget_ci->ca.write_cam_control = ciintf_write_cam_control;
529         budget_ci->ca.slot_reset = ciintf_slot_reset;
530         budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
531         budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
532         budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
533         budget_ci->ca.data = budget_ci;
534         if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
535                                           &budget_ci->ca,
536                                           ca_flags, 1)) != 0) {
537                 printk("budget_ci: CI interface detected, but initialisation failed.\n");
538                 goto error;
539         }
540
541         // Setup CI slot IRQ
542         if (budget_ci->ci_irq) {
543                 tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
544                 if (budget_ci->slot_status != SLOTSTATUS_NONE) {
545                         saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
546                 } else {
547                         saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
548                 }
549                 SAA7146_IER_ENABLE(saa, MASK_03);
550         }
551
552         // enable interface
553         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
554                                CICONTROL_RESET, 1, 0);
555
556         // success!
557         printk("budget_ci: CI interface initialised\n");
558         budget_ci->budget.ci_present = 1;
559
560         // forge a fake CI IRQ so the CAM state is setup correctly
561         if (budget_ci->ci_irq) {
562                 flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
563                 if (budget_ci->slot_status != SLOTSTATUS_NONE)
564                         flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
565                 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
566         }
567
568         return 0;
569
570 error:
571         saa7146_write(saa, MC1, MASK_27);
572         return result;
573 }
574
575 static void ciintf_deinit(struct budget_ci *budget_ci)
576 {
577         struct saa7146_dev *saa = budget_ci->budget.dev;
578
579         // disable CI interrupts
580         if (budget_ci->ci_irq) {
581                 SAA7146_IER_DISABLE(saa, MASK_03);
582                 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
583                 tasklet_kill(&budget_ci->ciintf_irq_tasklet);
584         }
585
586         // reset interface
587         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
588         msleep(1);
589         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
590                                CICONTROL_RESET, 1, 0);
591
592         // disable TS data stream to CI interface
593         saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
594
595         // release the CA device
596         dvb_ca_en50221_release(&budget_ci->ca);
597
598         // disable DEBI pins
599         saa7146_write(saa, MC1, MASK_27);
600 }
601
602 static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
603 {
604         struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
605
606         dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
607
608         if (*isr & MASK_06)
609                 tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
610
611         if (*isr & MASK_10)
612                 ttpci_budget_irq10_handler(dev, isr);
613
614         if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
615                 tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
616 }
617
618 static u8 philips_su1278_tt_inittab[] = {
619         0x01, 0x0f,
620         0x02, 0x30,
621         0x03, 0x00,
622         0x04, 0x5b,
623         0x05, 0x85,
624         0x06, 0x02,
625         0x07, 0x00,
626         0x08, 0x02,
627         0x09, 0x00,
628         0x0C, 0x01,
629         0x0D, 0x81,
630         0x0E, 0x44,
631         0x0f, 0x14,
632         0x10, 0x3c,
633         0x11, 0x84,
634         0x12, 0xda,
635         0x13, 0x97,
636         0x14, 0x95,
637         0x15, 0xc9,
638         0x16, 0x19,
639         0x17, 0x8c,
640         0x18, 0x59,
641         0x19, 0xf8,
642         0x1a, 0xfe,
643         0x1c, 0x7f,
644         0x1d, 0x00,
645         0x1e, 0x00,
646         0x1f, 0x50,
647         0x20, 0x00,
648         0x21, 0x00,
649         0x22, 0x00,
650         0x23, 0x00,
651         0x28, 0x00,
652         0x29, 0x28,
653         0x2a, 0x14,
654         0x2b, 0x0f,
655         0x2c, 0x09,
656         0x2d, 0x09,
657         0x31, 0x1f,
658         0x32, 0x19,
659         0x33, 0xfc,
660         0x34, 0x93,
661         0xff, 0xff
662 };
663
664 static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
665 {
666         stv0299_writereg(fe, 0x0e, 0x44);
667         if (srate >= 10000000) {
668                 stv0299_writereg(fe, 0x13, 0x97);
669                 stv0299_writereg(fe, 0x14, 0x95);
670                 stv0299_writereg(fe, 0x15, 0xc9);
671                 stv0299_writereg(fe, 0x17, 0x8c);
672                 stv0299_writereg(fe, 0x1a, 0xfe);
673                 stv0299_writereg(fe, 0x1c, 0x7f);
674                 stv0299_writereg(fe, 0x2d, 0x09);
675         } else {
676                 stv0299_writereg(fe, 0x13, 0x99);
677                 stv0299_writereg(fe, 0x14, 0x8d);
678                 stv0299_writereg(fe, 0x15, 0xce);
679                 stv0299_writereg(fe, 0x17, 0x43);
680                 stv0299_writereg(fe, 0x1a, 0x1d);
681                 stv0299_writereg(fe, 0x1c, 0x12);
682                 stv0299_writereg(fe, 0x2d, 0x05);
683         }
684         stv0299_writereg(fe, 0x0e, 0x23);
685         stv0299_writereg(fe, 0x0f, 0x94);
686         stv0299_writereg(fe, 0x10, 0x39);
687         stv0299_writereg(fe, 0x15, 0xc9);
688
689         stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
690         stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
691         stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
692
693         return 0;
694 }
695
696 static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe,
697                                            struct dvb_frontend_parameters *params)
698 {
699         struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
700         u32 div;
701         u8 buf[4];
702         struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
703
704         if ((params->frequency < 950000) || (params->frequency > 2150000))
705                 return -EINVAL;
706
707         div = (params->frequency + (500 - 1)) / 500;    // round correctly
708         buf[0] = (div >> 8) & 0x7f;
709         buf[1] = div & 0xff;
710         buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
711         buf[3] = 0x20;
712
713         if (params->u.qpsk.symbol_rate < 4000000)
714                 buf[3] |= 1;
715
716         if (params->frequency < 1250000)
717                 buf[3] |= 0;
718         else if (params->frequency < 1550000)
719                 buf[3] |= 0x40;
720         else if (params->frequency < 2050000)
721                 buf[3] |= 0x80;
722         else if (params->frequency < 2150000)
723                 buf[3] |= 0xC0;
724
725         if (fe->ops.i2c_gate_ctrl)
726                 fe->ops.i2c_gate_ctrl(fe, 1);
727         if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
728                 return -EIO;
729         return 0;
730 }
731
732 static struct stv0299_config philips_su1278_tt_config = {
733
734         .demod_address = 0x68,
735         .inittab = philips_su1278_tt_inittab,
736         .mclk = 64000000UL,
737         .invert = 0,
738         .skip_reinit = 1,
739         .lock_output = STV0299_LOCKOUTPUT_1,
740         .volt13_op0_op1 = STV0299_VOLT13_OP1,
741         .min_delay_ms = 50,
742         .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
743 };
744
745
746
747 static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
748 {
749         struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
750         static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
751         static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
752         struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
753                         sizeof(td1316_init) };
754
755         // setup PLL configuration
756         if (fe->ops.i2c_gate_ctrl)
757                 fe->ops.i2c_gate_ctrl(fe, 1);
758         if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
759                 return -EIO;
760         msleep(1);
761
762         // disable the mc44BC374c (do not check for errors)
763         tuner_msg.addr = 0x65;
764         tuner_msg.buf = disable_mc44BC374c;
765         tuner_msg.len = sizeof(disable_mc44BC374c);
766         if (fe->ops.i2c_gate_ctrl)
767                 fe->ops.i2c_gate_ctrl(fe, 1);
768         if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
769                 if (fe->ops.i2c_gate_ctrl)
770                         fe->ops.i2c_gate_ctrl(fe, 1);
771                 i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
772         }
773
774         return 0;
775 }
776
777 static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
778 {
779         struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
780         u8 tuner_buf[4];
781         struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
782         int tuner_frequency = 0;
783         u8 band, cp, filter;
784
785         // determine charge pump
786         tuner_frequency = params->frequency + 36130000;
787         if (tuner_frequency < 87000000)
788                 return -EINVAL;
789         else if (tuner_frequency < 130000000)
790                 cp = 3;
791         else if (tuner_frequency < 160000000)
792                 cp = 5;
793         else if (tuner_frequency < 200000000)
794                 cp = 6;
795         else if (tuner_frequency < 290000000)
796                 cp = 3;
797         else if (tuner_frequency < 420000000)
798                 cp = 5;
799         else if (tuner_frequency < 480000000)
800                 cp = 6;
801         else if (tuner_frequency < 620000000)
802                 cp = 3;
803         else if (tuner_frequency < 830000000)
804                 cp = 5;
805         else if (tuner_frequency < 895000000)
806                 cp = 7;
807         else
808                 return -EINVAL;
809
810         // determine band
811         if (params->frequency < 49000000)
812                 return -EINVAL;
813         else if (params->frequency < 159000000)
814                 band = 1;
815         else if (params->frequency < 444000000)
816                 band = 2;
817         else if (params->frequency < 861000000)
818                 band = 4;
819         else
820                 return -EINVAL;
821
822         // setup PLL filter and TDA9889
823         switch (params->u.ofdm.bandwidth) {
824         case BANDWIDTH_6_MHZ:
825                 tda1004x_writereg(fe, 0x0C, 0x14);
826                 filter = 0;
827                 break;
828
829         case BANDWIDTH_7_MHZ:
830                 tda1004x_writereg(fe, 0x0C, 0x80);
831                 filter = 0;
832                 break;
833
834         case BANDWIDTH_8_MHZ:
835                 tda1004x_writereg(fe, 0x0C, 0x14);
836                 filter = 1;
837                 break;
838
839         default:
840                 return -EINVAL;
841         }
842
843         // calculate divisor
844         // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
845         tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
846
847         // setup tuner buffer
848         tuner_buf[0] = tuner_frequency >> 8;
849         tuner_buf[1] = tuner_frequency & 0xff;
850         tuner_buf[2] = 0xca;
851         tuner_buf[3] = (cp << 5) | (filter << 3) | band;
852
853         if (fe->ops.i2c_gate_ctrl)
854                 fe->ops.i2c_gate_ctrl(fe, 1);
855         if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
856                 return -EIO;
857
858         msleep(1);
859         return 0;
860 }
861
862 static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
863                                              const struct firmware **fw, char *name)
864 {
865         struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
866
867         return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
868 }
869
870 static struct tda1004x_config philips_tdm1316l_config = {
871
872         .demod_address = 0x8,
873         .invert = 0,
874         .invert_oclk = 0,
875         .xtal_freq = TDA10046_XTAL_4M,
876         .agc_config = TDA10046_AGC_DEFAULT,
877         .if_freq = TDA10046_FREQ_3617,
878         .request_firmware = philips_tdm1316l_request_firmware,
879 };
880
881 static struct tda1004x_config philips_tdm1316l_config_invert = {
882
883         .demod_address = 0x8,
884         .invert = 1,
885         .invert_oclk = 0,
886         .xtal_freq = TDA10046_XTAL_4M,
887         .agc_config = TDA10046_AGC_DEFAULT,
888         .if_freq = TDA10046_FREQ_3617,
889         .request_firmware = philips_tdm1316l_request_firmware,
890 };
891
892 static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
893 {
894         struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
895         u8 tuner_buf[5];
896         struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
897                                     .flags = 0,
898                                     .buf = tuner_buf,
899                                     .len = sizeof(tuner_buf) };
900         int tuner_frequency = 0;
901         u8 band, cp, filter;
902
903         // determine charge pump
904         tuner_frequency = params->frequency + 36125000;
905         if (tuner_frequency < 87000000)
906                 return -EINVAL;
907         else if (tuner_frequency < 130000000) {
908                 cp = 3;
909                 band = 1;
910         } else if (tuner_frequency < 160000000) {
911                 cp = 5;
912                 band = 1;
913         } else if (tuner_frequency < 200000000) {
914                 cp = 6;
915                 band = 1;
916         } else if (tuner_frequency < 290000000) {
917                 cp = 3;
918                 band = 2;
919         } else if (tuner_frequency < 420000000) {
920                 cp = 5;
921                 band = 2;
922         } else if (tuner_frequency < 480000000) {
923                 cp = 6;
924                 band = 2;
925         } else if (tuner_frequency < 620000000) {
926                 cp = 3;
927                 band = 4;
928         } else if (tuner_frequency < 830000000) {
929                 cp = 5;
930                 band = 4;
931         } else if (tuner_frequency < 895000000) {
932                 cp = 7;
933                 band = 4;
934         } else
935                 return -EINVAL;
936
937         // assume PLL filter should always be 8MHz for the moment.
938         filter = 1;
939
940         // calculate divisor
941         tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500;
942
943         // setup tuner buffer
944         tuner_buf[0] = tuner_frequency >> 8;
945         tuner_buf[1] = tuner_frequency & 0xff;
946         tuner_buf[2] = 0xc8;
947         tuner_buf[3] = (cp << 5) | (filter << 3) | band;
948         tuner_buf[4] = 0x80;
949
950         if (fe->ops.i2c_gate_ctrl)
951                 fe->ops.i2c_gate_ctrl(fe, 1);
952         if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
953                 return -EIO;
954
955         msleep(50);
956
957         if (fe->ops.i2c_gate_ctrl)
958                 fe->ops.i2c_gate_ctrl(fe, 1);
959         if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
960                 return -EIO;
961
962         msleep(1);
963
964         return 0;
965 }
966
967 static u8 dvbc_philips_tdm1316l_inittab[] = {
968         0x80, 0x01,
969         0x80, 0x00,
970         0x81, 0x01,
971         0x81, 0x00,
972         0x00, 0x09,
973         0x01, 0x69,
974         0x03, 0x00,
975         0x04, 0x00,
976         0x07, 0x00,
977         0x08, 0x00,
978         0x20, 0x00,
979         0x21, 0x40,
980         0x22, 0x00,
981         0x23, 0x00,
982         0x24, 0x40,
983         0x25, 0x88,
984         0x30, 0xff,
985         0x31, 0x00,
986         0x32, 0xff,
987         0x33, 0x00,
988         0x34, 0x50,
989         0x35, 0x7f,
990         0x36, 0x00,
991         0x37, 0x20,
992         0x38, 0x00,
993         0x40, 0x1c,
994         0x41, 0xff,
995         0x42, 0x29,
996         0x43, 0x20,
997         0x44, 0xff,
998         0x45, 0x00,
999         0x46, 0x00,
1000         0x49, 0x04,
1001         0x4a, 0x00,
1002         0x4b, 0x7b,
1003         0x52, 0x30,
1004         0x55, 0xae,
1005         0x56, 0x47,
1006         0x57, 0xe1,
1007         0x58, 0x3a,
1008         0x5a, 0x1e,
1009         0x5b, 0x34,
1010         0x60, 0x00,
1011         0x63, 0x00,
1012         0x64, 0x00,
1013         0x65, 0x00,
1014         0x66, 0x00,
1015         0x67, 0x00,
1016         0x68, 0x00,
1017         0x69, 0x00,
1018         0x6a, 0x02,
1019         0x6b, 0x00,
1020         0x70, 0xff,
1021         0x71, 0x00,
1022         0x72, 0x00,
1023         0x73, 0x00,
1024         0x74, 0x0c,
1025         0x80, 0x00,
1026         0x81, 0x00,
1027         0x82, 0x00,
1028         0x83, 0x00,
1029         0x84, 0x04,
1030         0x85, 0x80,
1031         0x86, 0x24,
1032         0x87, 0x78,
1033         0x88, 0x10,
1034         0x89, 0x00,
1035         0x90, 0x01,
1036         0x91, 0x01,
1037         0xa0, 0x04,
1038         0xa1, 0x00,
1039         0xa2, 0x00,
1040         0xb0, 0x91,
1041         0xb1, 0x0b,
1042         0xc0, 0x53,
1043         0xc1, 0x70,
1044         0xc2, 0x12,
1045         0xd0, 0x00,
1046         0xd1, 0x00,
1047         0xd2, 0x00,
1048         0xd3, 0x00,
1049         0xd4, 0x00,
1050         0xd5, 0x00,
1051         0xde, 0x00,
1052         0xdf, 0x00,
1053         0x61, 0x38,
1054         0x62, 0x0a,
1055         0x53, 0x13,
1056         0x59, 0x08,
1057         0xff, 0xff,
1058 };
1059
1060 static struct stv0297_config dvbc_philips_tdm1316l_config = {
1061         .demod_address = 0x1c,
1062         .inittab = dvbc_philips_tdm1316l_inittab,
1063         .invert = 0,
1064         .stop_during_read = 1,
1065 };
1066
1067 static struct tda10023_config tda10023_config = {
1068         .demod_address = 0xc,
1069         .invert = 0,
1070         .xtal = 16000000,
1071         .pll_m = 11,
1072         .pll_p = 3,
1073         .pll_n = 1,
1074         .deltaf = 0xa511,
1075 };
1076
1077 /* TT S2-3200 DVB-S (STB0899) Inittab */
1078 static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
1079
1080 //       0x0000000b ,   /* SYSREG */
1081         { STB0899_DEV_ID                , 0x81 },
1082         { STB0899_DISCNTRL1             , 0x32 },
1083         { STB0899_DISCNTRL2             , 0x80 },
1084         { STB0899_DISRX_ST0             , 0x04 },
1085         { STB0899_DISRX_ST1             , 0x00 },
1086         { STB0899_DISPARITY             , 0x00 },
1087         { STB0899_DISFIFO               , 0x00 },
1088         { STB0899_DISSTATUS             , 0x20 },
1089         { STB0899_DISF22                , 0x8c },
1090         { STB0899_DISF22RX              , 0x9a },
1091         //SYSREG ?
1092         { STB0899_ACRPRESC              , 0x11 },
1093         { STB0899_ACRDIV1               , 0x0a },
1094         { STB0899_ACRDIV2               , 0x05 },
1095         { STB0899_DACR1                 , 0x00 },
1096         { STB0899_DACR2                 , 0x00 },
1097         { STB0899_OUTCFG                , 0x00 },
1098         { STB0899_MODECFG               , 0x00 },
1099         { STB0899_IRQSTATUS_3           , 0x30 },
1100         { STB0899_IRQSTATUS_2           , 0x00 },
1101         { STB0899_IRQSTATUS_1           , 0x00 },
1102         { STB0899_IRQSTATUS_0           , 0x00 },
1103         { STB0899_IRQMSK_3              , 0xf3 },
1104         { STB0899_IRQMSK_2              , 0xfc },
1105         { STB0899_IRQMSK_1              , 0xff },
1106         { STB0899_IRQMSK_0              , 0xff },
1107         { STB0899_IRQCFG                , 0x00 },
1108         { STB0899_I2CCFG                , 0x88 },
1109         { STB0899_I2CRPT                , 0x5c },
1110         { STB0899_IOPVALUE5             , 0x00 },
1111         { STB0899_IOPVALUE4             , 0x20 },
1112         { STB0899_IOPVALUE3             , 0xc9 },
1113         { STB0899_IOPVALUE2             , 0x90 },
1114         { STB0899_IOPVALUE1             , 0x40 },
1115         { STB0899_IOPVALUE0             , 0x00 },
1116         { STB0899_GPIO00CFG             , 0x82 },
1117         { STB0899_GPIO01CFG             , 0x82 },
1118         { STB0899_GPIO02CFG             , 0x82 },
1119         { STB0899_GPIO03CFG             , 0x82 },
1120         { STB0899_GPIO04CFG             , 0x82 },
1121         { STB0899_GPIO05CFG             , 0x82 },
1122         { STB0899_GPIO06CFG             , 0x82 },
1123         { STB0899_GPIO07CFG             , 0x82 },
1124         { STB0899_GPIO08CFG             , 0x82 },
1125         { STB0899_GPIO09CFG             , 0x82 },
1126         { STB0899_GPIO10CFG             , 0x82 },
1127         { STB0899_GPIO11CFG             , 0x82 },
1128         { STB0899_GPIO12CFG             , 0x82 },
1129         { STB0899_GPIO13CFG             , 0x82 },
1130         { STB0899_GPIO14CFG             , 0x82 },
1131         { STB0899_GPIO15CFG             , 0x82 },
1132         { STB0899_GPIO16CFG             , 0x82 },
1133         { STB0899_GPIO17CFG             , 0x82 },
1134         { STB0899_GPIO18CFG             , 0x82 },
1135         { STB0899_GPIO19CFG             , 0x82 },
1136         { STB0899_GPIO20CFG             , 0x82 },
1137         { STB0899_SDATCFG               , 0xb8 },
1138         { STB0899_SCLTCFG               , 0xba },
1139         { STB0899_AGCRFCFG              , 0x1c }, /* 0x11 */
1140         { STB0899_GPIO22                , 0x82 }, /* AGCBB2CFG */
1141         { STB0899_GPIO21                , 0x91 }, /* AGCBB1CFG */
1142         { STB0899_DIRCLKCFG             , 0x82 },
1143         { STB0899_CLKOUT27CFG           , 0x7e },
1144         { STB0899_STDBYCFG              , 0x82 },
1145         { STB0899_CS0CFG                , 0x82 },
1146         { STB0899_CS1CFG                , 0x82 },
1147         { STB0899_DISEQCOCFG            , 0x20 },
1148         { STB0899_GPIO32CFG             , 0x82 },
1149         { STB0899_GPIO33CFG             , 0x82 },
1150         { STB0899_GPIO34CFG             , 0x82 },
1151         { STB0899_GPIO35CFG             , 0x82 },
1152         { STB0899_GPIO36CFG             , 0x82 },
1153         { STB0899_GPIO37CFG             , 0x82 },
1154         { STB0899_GPIO38CFG             , 0x82 },
1155         { STB0899_GPIO39CFG             , 0x82 },
1156         { STB0899_NCOARSE               , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
1157         { STB0899_SYNTCTRL              , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
1158         { STB0899_FILTCTRL              , 0x00 },
1159         { STB0899_SYSCTRL               , 0x00 },
1160         { STB0899_STOPCLK1              , 0x20 },
1161         { STB0899_STOPCLK2              , 0x00 },
1162         { STB0899_INTBUFSTATUS          , 0x00 },
1163         { STB0899_INTBUFCTRL            , 0x0a },
1164         { 0xffff                        , 0xff },
1165 };
1166
1167 static const struct stb0899_s2_reg  tt3200_stb0899_s2_init_2[] = {
1168
1169         { STB0899_OFF0_DMD_STATUS       , STB0899_BASE_DMD_STATUS       , 0x00000103 }, /* DMDSTATUS    */
1170         { STB0899_OFF0_CRL_FREQ         , STB0899_BASE_CRL_FREQ         , 0x3ed1da56 }, /* CRLFREQ      */
1171         { STB0899_OFF0_BTR_FREQ         , STB0899_BASE_BTR_FREQ         , 0x00004000 }, /* BTRFREQ      */
1172         { STB0899_OFF0_IF_AGC_GAIN      , STB0899_BASE_IF_AGC_GAIN      , 0x00002ade }, /* IFAGCGAIN    */
1173         { STB0899_OFF0_BB_AGC_GAIN      , STB0899_BASE_BB_AGC_GAIN      , 0x000001bc }, /* BBAGCGAIN    */
1174         { STB0899_OFF0_DC_OFFSET        , STB0899_BASE_DC_OFFSET        , 0x00000200 }, /* DCOFFSET     */
1175         { STB0899_OFF0_DMD_CNTRL        , STB0899_BASE_DMD_CNTRL        , 0x0000000f }, /* DMDCNTRL     */
1176
1177         { STB0899_OFF0_IF_AGC_CNTRL     , STB0899_BASE_IF_AGC_CNTRL     , 0x03fb4a20 }, /* IFAGCCNTRL   */
1178         { STB0899_OFF0_BB_AGC_CNTRL     , STB0899_BASE_BB_AGC_CNTRL     , 0x00200c97 }, /* BBAGCCNTRL   */
1179
1180         { STB0899_OFF0_CRL_CNTRL        , STB0899_BASE_CRL_CNTRL        , 0x00000016 }, /* CRLCNTRL     */
1181         { STB0899_OFF0_CRL_PHS_INIT     , STB0899_BASE_CRL_PHS_INIT     , 0x00000000 }, /* CRLPHSINIT   */
1182         { STB0899_OFF0_CRL_FREQ_INIT    , STB0899_BASE_CRL_FREQ_INIT    , 0x00000000 }, /* CRLFREQINIT  */
1183         { STB0899_OFF0_CRL_LOOP_GAIN    , STB0899_BASE_CRL_LOOP_GAIN    , 0x00000000 }, /* CRLLOOPGAIN  */
1184         { STB0899_OFF0_CRL_NOM_FREQ     , STB0899_BASE_CRL_NOM_FREQ     , 0x3ed097b6 }, /* CRLNOMFREQ   */
1185         { STB0899_OFF0_CRL_SWP_RATE     , STB0899_BASE_CRL_SWP_RATE     , 0x00000000 }, /* CRLSWPRATE   */
1186         { STB0899_OFF0_CRL_MAX_SWP      , STB0899_BASE_CRL_MAX_SWP      , 0x00000000 }, /* CRLMAXSWP    */
1187         { STB0899_OFF0_CRL_LK_CNTRL     , STB0899_BASE_CRL_LK_CNTRL     , 0x0f6cdc01 }, /* CRLLKCNTRL   */
1188         { STB0899_OFF0_DECIM_CNTRL      , STB0899_BASE_DECIM_CNTRL      , 0x00000000 }, /* DECIMCNTRL   */
1189         { STB0899_OFF0_BTR_CNTRL        , STB0899_BASE_BTR_CNTRL        , 0x00003993 }, /* BTRCNTRL     */
1190         { STB0899_OFF0_BTR_LOOP_GAIN    , STB0899_BASE_BTR_LOOP_GAIN    , 0x000d3c6f }, /* BTRLOOPGAIN  */
1191         { STB0899_OFF0_BTR_PHS_INIT     , STB0899_BASE_BTR_PHS_INIT     , 0x00000000 }, /* BTRPHSINIT   */
1192         { STB0899_OFF0_BTR_FREQ_INIT    , STB0899_BASE_BTR_FREQ_INIT    , 0x00000000 }, /* BTRFREQINIT  */
1193         { STB0899_OFF0_BTR_NOM_FREQ     , STB0899_BASE_BTR_NOM_FREQ     , 0x0238e38e }, /* BTRNOMFREQ   */
1194         { STB0899_OFF0_BTR_LK_CNTRL     , STB0899_BASE_BTR_LK_CNTRL     , 0x00000000 }, /* BTRLKCNTRL   */
1195         { STB0899_OFF0_DECN_CNTRL       , STB0899_BASE_DECN_CNTRL       , 0x00000000 }, /* DECNCNTRL    */
1196         { STB0899_OFF0_TP_CNTRL         , STB0899_BASE_TP_CNTRL         , 0x00000000 }, /* TPCNTRL      */
1197         { STB0899_OFF0_TP_BUF_STATUS    , STB0899_BASE_TP_BUF_STATUS    , 0x00000000 }, /* TPBUFSTATUS  */
1198         { STB0899_OFF0_DC_ESTIM         , STB0899_BASE_DC_ESTIM         , 0x00000000 }, /* DCESTIM      */
1199         { STB0899_OFF0_FLL_CNTRL        , STB0899_BASE_FLL_CNTRL        , 0x00000000 }, /* FLLCNTRL     */
1200         { STB0899_OFF0_FLL_FREQ_WD      , STB0899_BASE_FLL_FREQ_WD      , 0x40070000 }, /* FLLFREQWD    */
1201         { STB0899_OFF0_ANTI_ALIAS_SEL   , STB0899_BASE_ANTI_ALIAS_SEL   , 0x00000001 }, /* ANTIALIASSEL */
1202         { STB0899_OFF0_RRC_ALPHA        , STB0899_BASE_RRC_ALPHA        , 0x00000002 }, /* RRCALPHA     */
1203         { STB0899_OFF0_DC_ADAPT_LSHFT   , STB0899_BASE_DC_ADAPT_LSHFT   , 0x00000000 }, /* DCADAPTISHFT */
1204         { STB0899_OFF0_IMB_OFFSET       , STB0899_BASE_IMB_OFFSET       , 0x0000fe01 }, /* IMBOFFSET    */
1205         { STB0899_OFF0_IMB_ESTIMATE     , STB0899_BASE_IMB_ESTIMATE     , 0x00000000 }, /* IMBESTIMATE  */
1206         { STB0899_OFF0_IMB_CNTRL        , STB0899_BASE_IMB_CNTRL        , 0x00000001 }, /* IMBCNTRL     */
1207         { STB0899_OFF0_IF_AGC_CNTRL2    , STB0899_BASE_IF_AGC_CNTRL2    , 0x00005007 }, /* IFAGCCNTRL2  */
1208         { STB0899_OFF0_DMD_CNTRL2       , STB0899_BASE_DMD_CNTRL2       , 0x00000002 }, /* DMDCNTRL2    */
1209         { STB0899_OFF0_TP_BUFFER        , STB0899_BASE_TP_BUFFER        , 0x00000000 }, /* TPBUFFER     */
1210         { STB0899_OFF0_TP_BUFFER1       , STB0899_BASE_TP_BUFFER1       , 0x00000000 }, /* TPBUFFER1    */
1211         { STB0899_OFF0_TP_BUFFER2       , STB0899_BASE_TP_BUFFER2       , 0x00000000 }, /* TPBUFFER2    */
1212         { STB0899_OFF0_TP_BUFFER3       , STB0899_BASE_TP_BUFFER3       , 0x00000000 }, /* TPBUFFER3    */
1213         { STB0899_OFF0_TP_BUFFER4       , STB0899_BASE_TP_BUFFER4       , 0x00000000 }, /* TPBUFFER4    */
1214         { STB0899_OFF0_TP_BUFFER5       , STB0899_BASE_TP_BUFFER5       , 0x00000000 }, /* TPBUFFER5    */
1215         { STB0899_OFF0_TP_BUFFER6       , STB0899_BASE_TP_BUFFER6       , 0x00000000 }, /* TPBUFFER6    */
1216         { STB0899_OFF0_TP_BUFFER7       , STB0899_BASE_TP_BUFFER7       , 0x00000000 }, /* TPBUFFER7    */
1217         { STB0899_OFF0_TP_BUFFER8       , STB0899_BASE_TP_BUFFER8       , 0x00000000 }, /* TPBUFFER8    */
1218         { STB0899_OFF0_TP_BUFFER9       , STB0899_BASE_TP_BUFFER9       , 0x00000000 }, /* TPBUFFER9    */
1219         { STB0899_OFF0_TP_BUFFER10      , STB0899_BASE_TP_BUFFER10      , 0x00000000 }, /* TPBUFFER10   */
1220         { STB0899_OFF0_TP_BUFFER11      , STB0899_BASE_TP_BUFFER11      , 0x00000000 }, /* TPBUFFER11   */
1221         { STB0899_OFF0_TP_BUFFER12      , STB0899_BASE_TP_BUFFER12      , 0x00000000 }, /* TPBUFFER12   */
1222         { STB0899_OFF0_TP_BUFFER13      , STB0899_BASE_TP_BUFFER13      , 0x00000000 }, /* TPBUFFER13   */
1223         { STB0899_OFF0_TP_BUFFER14      , STB0899_BASE_TP_BUFFER14      , 0x00000000 }, /* TPBUFFER14   */
1224         { STB0899_OFF0_TP_BUFFER15      , STB0899_BASE_TP_BUFFER15      , 0x00000000 }, /* TPBUFFER15   */
1225         { STB0899_OFF0_TP_BUFFER16      , STB0899_BASE_TP_BUFFER16      , 0x0000ff00 }, /* TPBUFFER16   */
1226         { STB0899_OFF0_TP_BUFFER17      , STB0899_BASE_TP_BUFFER17      , 0x00000100 }, /* TPBUFFER17   */
1227         { STB0899_OFF0_TP_BUFFER18      , STB0899_BASE_TP_BUFFER18      , 0x0000fe01 }, /* TPBUFFER18   */
1228         { STB0899_OFF0_TP_BUFFER19      , STB0899_BASE_TP_BUFFER19      , 0x000004fe }, /* TPBUFFER19   */
1229         { STB0899_OFF0_TP_BUFFER20      , STB0899_BASE_TP_BUFFER20      , 0x0000cfe7 }, /* TPBUFFER20   */
1230         { STB0899_OFF0_TP_BUFFER21      , STB0899_BASE_TP_BUFFER21      , 0x0000bec6 }, /* TPBUFFER21   */
1231         { STB0899_OFF0_TP_BUFFER22      , STB0899_BASE_TP_BUFFER22      , 0x0000c2bf }, /* TPBUFFER22   */
1232         { STB0899_OFF0_TP_BUFFER23      , STB0899_BASE_TP_BUFFER23      , 0x0000c1c1 }, /* TPBUFFER23   */
1233         { STB0899_OFF0_TP_BUFFER24      , STB0899_BASE_TP_BUFFER24      , 0x0000c1c1 }, /* TPBUFFER24   */
1234         { STB0899_OFF0_TP_BUFFER25      , STB0899_BASE_TP_BUFFER25      , 0x0000c1c1 }, /* TPBUFFER25   */
1235         { STB0899_OFF0_TP_BUFFER26      , STB0899_BASE_TP_BUFFER26      , 0x0000c1c1 }, /* TPBUFFER26   */
1236         { STB0899_OFF0_TP_BUFFER27      , STB0899_BASE_TP_BUFFER27      , 0x0000c1c0 }, /* TPBUFFER27   */
1237         { STB0899_OFF0_TP_BUFFER28      , STB0899_BASE_TP_BUFFER28      , 0x0000c0c0 }, /* TPBUFFER28   */
1238         { STB0899_OFF0_TP_BUFFER29      , STB0899_BASE_TP_BUFFER29      , 0x0000c1c1 }, /* TPBUFFER29   */
1239         { STB0899_OFF0_TP_BUFFER30      , STB0899_BASE_TP_BUFFER30      , 0x0000c1c1 }, /* TPBUFFER30   */
1240         { STB0899_OFF0_TP_BUFFER31      , STB0899_BASE_TP_BUFFER31      , 0x0000c0c1 }, /* TPBUFFER31   */
1241         { STB0899_OFF0_TP_BUFFER32      , STB0899_BASE_TP_BUFFER32      , 0x0000c0c1 }, /* TPBUFFER32   */
1242         { STB0899_OFF0_TP_BUFFER33      , STB0899_BASE_TP_BUFFER33      , 0x0000c1c1 }, /* TPBUFFER33   */
1243         { STB0899_OFF0_TP_BUFFER34      , STB0899_BASE_TP_BUFFER34      , 0x0000c1c1 }, /* TPBUFFER34   */
1244         { STB0899_OFF0_TP_BUFFER35      , STB0899_BASE_TP_BUFFER35      , 0x0000c0c1 }, /* TPBUFFER35   */
1245         { STB0899_OFF0_TP_BUFFER36      , STB0899_BASE_TP_BUFFER36      , 0x0000c1c1 }, /* TPBUFFER36   */
1246         { STB0899_OFF0_TP_BUFFER37      , STB0899_BASE_TP_BUFFER37      , 0x0000c0c1 }, /* TPBUFFER37   */
1247         { STB0899_OFF0_TP_BUFFER38      , STB0899_BASE_TP_BUFFER38      , 0x0000c1c1 }, /* TPBUFFER38   */
1248         { STB0899_OFF0_TP_BUFFER39      , STB0899_BASE_TP_BUFFER39      , 0x0000c0c0 }, /* TPBUFFER39   */
1249         { STB0899_OFF0_TP_BUFFER40      , STB0899_BASE_TP_BUFFER40      , 0x0000c1c0 }, /* TPBUFFER40   */
1250         { STB0899_OFF0_TP_BUFFER41      , STB0899_BASE_TP_BUFFER41      , 0x0000c1c1 }, /* TPBUFFER41   */
1251         { STB0899_OFF0_TP_BUFFER42      , STB0899_BASE_TP_BUFFER42      , 0x0000c0c0 }, /* TPBUFFER42   */
1252         { STB0899_OFF0_TP_BUFFER43      , STB0899_BASE_TP_BUFFER43      , 0x0000c1c0 }, /* TPBUFFER43   */
1253         { STB0899_OFF0_TP_BUFFER44      , STB0899_BASE_TP_BUFFER44      , 0x0000c0c1 }, /* TPBUFFER44   */
1254         { STB0899_OFF0_TP_BUFFER45      , STB0899_BASE_TP_BUFFER45      , 0x0000c1be }, /* TPBUFFER45   */
1255         { STB0899_OFF0_TP_BUFFER46      , STB0899_BASE_TP_BUFFER46      , 0x0000c1c9 }, /* TPBUFFER46   */
1256         { STB0899_OFF0_TP_BUFFER47      , STB0899_BASE_TP_BUFFER47      , 0x0000c0da }, /* TPBUFFER47   */
1257         { STB0899_OFF0_TP_BUFFER48      , STB0899_BASE_TP_BUFFER48      , 0x0000c0ba }, /* TPBUFFER48   */
1258         { STB0899_OFF0_TP_BUFFER49      , STB0899_BASE_TP_BUFFER49      , 0x0000c1c4 }, /* TPBUFFER49   */
1259         { STB0899_OFF0_TP_BUFFER50      , STB0899_BASE_TP_BUFFER50      , 0x0000c1bf }, /* TPBUFFER50   */
1260         { STB0899_OFF0_TP_BUFFER51      , STB0899_BASE_TP_BUFFER51      , 0x0000c0c1 }, /* TPBUFFER51   */
1261         { STB0899_OFF0_TP_BUFFER52      , STB0899_BASE_TP_BUFFER52      , 0x0000c1c0 }, /* TPBUFFER52   */
1262         { STB0899_OFF0_TP_BUFFER53      , STB0899_BASE_TP_BUFFER53      , 0x0000c0c1 }, /* TPBUFFER53   */
1263         { STB0899_OFF0_TP_BUFFER54      , STB0899_BASE_TP_BUFFER54      , 0x0000c1c1 }, /* TPBUFFER54   */
1264         { STB0899_OFF0_TP_BUFFER55      , STB0899_BASE_TP_BUFFER55      , 0x0000c1c1 }, /* TPBUFFER55   */
1265         { STB0899_OFF0_TP_BUFFER56      , STB0899_BASE_TP_BUFFER56      , 0x0000c1c1 }, /* TPBUFFER56   */
1266         { STB0899_OFF0_TP_BUFFER57      , STB0899_BASE_TP_BUFFER57      , 0x0000c1c1 }, /* TPBUFFER57   */
1267         { STB0899_OFF0_TP_BUFFER58      , STB0899_BASE_TP_BUFFER58      , 0x0000c1c1 }, /* TPBUFFER58   */
1268         { STB0899_OFF0_TP_BUFFER59      , STB0899_BASE_TP_BUFFER59      , 0x0000c1c1 }, /* TPBUFFER59   */
1269         { STB0899_OFF0_TP_BUFFER60      , STB0899_BASE_TP_BUFFER60      , 0x0000c1c1 }, /* TPBUFFER60   */
1270         { STB0899_OFF0_TP_BUFFER61      , STB0899_BASE_TP_BUFFER61      , 0x0000c1c1 }, /* TPBUFFER61   */
1271         { STB0899_OFF0_TP_BUFFER62      , STB0899_BASE_TP_BUFFER62      , 0x0000c1c1 }, /* TPBUFFER62   */
1272         { STB0899_OFF0_TP_BUFFER63      , STB0899_BASE_TP_BUFFER63      , 0x0000c1c0 }, /* TPBUFFER63   */
1273         { STB0899_OFF0_RESET_CNTRL      , STB0899_BASE_RESET_CNTRL      , 0x00000001 }, /* RESETCNTRL   */
1274         { STB0899_OFF0_ACM_ENABLE       , STB0899_BASE_ACM_ENABLE       , 0x00005654 }, /* ACMENABLE    */
1275         { STB0899_OFF0_DESCR_CNTRL      , STB0899_BASE_DESCR_CNTRL      , 0x00000000 }, /* DESCRCNTRL   */
1276         { STB0899_OFF0_CSM_CNTRL1       , STB0899_BASE_CSM_CNTRL1       , 0x00020019 }, /* CSMCNTRL1    */
1277         { STB0899_OFF0_CSM_CNTRL2       , STB0899_BASE_CSM_CNTRL2       , 0x004b3237 }, /* CSMCNTRL2    */
1278         { STB0899_OFF0_CSM_CNTRL3       , STB0899_BASE_CSM_CNTRL3       , 0x0003dd17 }, /* CSMCNTRL3    */
1279         { STB0899_OFF0_CSM_CNTRL4       , STB0899_BASE_CSM_CNTRL4       , 0x00008008 }, /* CSMCNTRL4    */
1280         { STB0899_OFF0_UWP_CNTRL1       , STB0899_BASE_UWP_CNTRL1       , 0x002a3106 }, /* UWPCNTRL1    */
1281         { STB0899_OFF0_UWP_CNTRL2       , STB0899_BASE_UWP_CNTRL2       , 0x0006140a }, /* UWPCNTRL2    */
1282         { STB0899_OFF0_UWP_STAT1        , STB0899_BASE_UWP_STAT1        , 0x00008000 }, /* UWPSTAT1     */
1283         { STB0899_OFF0_UWP_STAT2        , STB0899_BASE_UWP_STAT2        , 0x00000000 }, /* UWPSTAT2     */
1284         { STB0899_OFF0_DMD_STAT2        , STB0899_BASE_DMD_STAT2        , 0x00000000 }, /* DMDSTAT2     */
1285         { STB0899_OFF0_FREQ_ADJ_SCALE   , STB0899_BASE_FREQ_ADJ_SCALE   , 0x00000471 }, /* FREQADJSCALE */
1286         { STB0899_OFF0_UWP_CNTRL3       , STB0899_BASE_UWP_CNTRL3       , 0x017b0465 }, /* UWPCNTRL3    */
1287         { STB0899_OFF0_SYM_CLK_SEL      , STB0899_BASE_SYM_CLK_SEL      , 0x00000002 }, /* SYMCLKSEL    */
1288         { STB0899_OFF0_SOF_SRCH_TO      , STB0899_BASE_SOF_SRCH_TO      , 0x00196464 }, /* SOFSRCHTO    */
1289         { STB0899_OFF0_ACQ_CNTRL1       , STB0899_BASE_ACQ_CNTRL1       , 0x00000603 }, /* ACQCNTRL1    */
1290         { STB0899_OFF0_ACQ_CNTRL2       , STB0899_BASE_ACQ_CNTRL2       , 0x02046666 }, /* ACQCNTRL2    */
1291         { STB0899_OFF0_ACQ_CNTRL3       , STB0899_BASE_ACQ_CNTRL3       , 0x10046583 }, /* ACQCNTRL3    */
1292         { STB0899_OFF0_FE_SETTLE        , STB0899_BASE_FE_SETTLE        , 0x00010404 }, /* FESETTLE     */
1293         { STB0899_OFF0_AC_DWELL         , STB0899_BASE_AC_DWELL         , 0x0002aa8a }, /* ACDWELL      */
1294         { STB0899_OFF0_ACQUIRE_TRIG     , STB0899_BASE_ACQUIRE_TRIG     , 0x00000000 }, /* ACQUIRETRIG  */
1295         { STB0899_OFF0_LOCK_LOST        , STB0899_BASE_LOCK_LOST        , 0x00000001 }, /* LOCKLOST     */
1296         { STB0899_OFF0_ACQ_STAT1        , STB0899_BASE_ACQ_STAT1        , 0x00000500 }, /* ACQSTAT1     */
1297         { STB0899_OFF0_ACQ_TIMEOUT      , STB0899_BASE_ACQ_TIMEOUT      , 0x0028a0a0 }, /* ACQTIMEOUT   */
1298         { STB0899_OFF0_ACQ_TIME         , STB0899_BASE_ACQ_TIME         , 0x00000000 }, /* ACQTIME      */
1299         { STB0899_OFF0_FINAL_AGC_CNTRL  , STB0899_BASE_FINAL_AGC_CNTRL  , 0x00800c17 }, /* FINALAGCCNTRL*/
1300         { STB0899_OFF0_FINAL_AGC_GAIN   , STB0899_BASE_FINAL_AGC_GAIN   , 0x00000000 }, /* FINALAGCCGAIN*/
1301         { STB0899_OFF0_EQUALIZER_INIT   , STB0899_BASE_EQUALIZER_INIT   , 0x00000000 }, /* EQUILIZERINIT*/
1302         { STB0899_OFF0_EQ_CNTRL         , STB0899_BASE_EQ_CNTRL         , 0x00054802 }, /* EQCNTL       */
1303         { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */
1304         { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */
1305         { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */
1306         { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */
1307         { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */
1308         { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */
1309         { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */
1310         { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */
1311         { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */
1312         { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */
1313         { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/
1314         { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */
1315         { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */
1316         { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */
1317         { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */
1318         { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */
1319         { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */
1320         { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */
1321         { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */
1322         { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */
1323         { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */
1324         { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/
1325         { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */
1326         { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */
1327         { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */
1328         { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */
1329         { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */
1330         { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */
1331         { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */
1332         { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */
1333         { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */
1334         { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */
1335         { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N  , 0x00000000 }, /* EQICOEFFSOUT10*/
1336         { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */
1337         { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */
1338         { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */
1339         { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */
1340         { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */
1341         { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */
1342         { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */
1343         { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */
1344         { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */
1345         { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */
1346         { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/
1347         { 0xffff                        , 0xffffffff                    , 0xffffffff },
1348 };
1349
1350 static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
1351         { STB0899_DEMOD                 , 0x00 },
1352         { STB0899_RCOMPC                , 0xc9 },
1353         { STB0899_AGC1CN                , 0x41 },
1354         { STB0899_AGC1REF               , 0x10 },
1355         { STB0899_RTC                   , 0x7a },
1356         { STB0899_TMGCFG                , 0x4e },
1357         { STB0899_AGC2REF               , 0x34 },
1358         { STB0899_TLSR                  , 0x84 },
1359         { STB0899_CFD                   , 0xc7 },
1360         { STB0899_ACLC                  , 0x87 },
1361         { STB0899_BCLC                  , 0x94 },
1362         { STB0899_EQON                  , 0x41 },
1363         { STB0899_LDT                   , 0xdd },
1364         { STB0899_LDT2                  , 0xc9 },
1365         { STB0899_EQUALREF              , 0xb4 },
1366         { STB0899_TMGRAMP               , 0x10 },
1367         { STB0899_TMGTHD                , 0x30 },
1368         { STB0899_IDCCOMP               , 0xfb },
1369         { STB0899_QDCCOMP               , 0x03 },
1370         { STB0899_POWERI                , 0x3b },
1371         { STB0899_POWERQ                , 0x3d },
1372         { STB0899_RCOMP                 , 0x81 },
1373         { STB0899_AGCIQIN               , 0x80 },
1374         { STB0899_AGC2I1                , 0x04 },
1375         { STB0899_AGC2I2                , 0xf5 },
1376         { STB0899_TLIR                  , 0x25 },
1377         { STB0899_RTF                   , 0x80 },
1378         { STB0899_DSTATUS               , 0x00 },
1379         { STB0899_LDI                   , 0xca },
1380         { STB0899_CFRM                  , 0xf1 },
1381         { STB0899_CFRL                  , 0xf3 },
1382         { STB0899_NIRM                  , 0x2a },
1383         { STB0899_NIRL                  , 0x05 },
1384         { STB0899_ISYMB                 , 0x17 },
1385         { STB0899_QSYMB                 , 0xfa },
1386         { STB0899_SFRH                  , 0x2f },
1387         { STB0899_SFRM                  , 0x68 },
1388         { STB0899_SFRL                  , 0x40 },
1389         { STB0899_SFRUPH                , 0x2f },
1390         { STB0899_SFRUPM                , 0x68 },
1391         { STB0899_SFRUPL                , 0x40 },
1392         { STB0899_EQUAI1                , 0xfd },
1393         { STB0899_EQUAQ1                , 0x04 },
1394         { STB0899_EQUAI2                , 0x0f },
1395         { STB0899_EQUAQ2                , 0xff },
1396         { STB0899_EQUAI3                , 0xdf },
1397         { STB0899_EQUAQ3                , 0xfa },
1398         { STB0899_EQUAI4                , 0x37 },
1399         { STB0899_EQUAQ4                , 0x0d },
1400         { STB0899_EQUAI5                , 0xbd },
1401         { STB0899_EQUAQ5                , 0xf7 },
1402         { STB0899_DSTATUS2              , 0x00 },
1403         { STB0899_VSTATUS               , 0x00 },
1404         { STB0899_VERROR                , 0xff },
1405         { STB0899_IQSWAP                , 0x2a },
1406         { STB0899_ECNT1M                , 0x00 },
1407         { STB0899_ECNT1L                , 0x00 },
1408         { STB0899_ECNT2M                , 0x00 },
1409         { STB0899_ECNT2L                , 0x00 },
1410         { STB0899_ECNT3M                , 0x00 },
1411         { STB0899_ECNT3L                , 0x00 },
1412         { STB0899_FECAUTO1              , 0x06 },
1413         { STB0899_FECM                  , 0x01 },
1414         { STB0899_VTH12                 , 0xf0 },
1415         { STB0899_VTH23                 , 0xa0 },
1416         { STB0899_VTH34                 , 0x78 },
1417         { STB0899_VTH56                 , 0x4e },
1418         { STB0899_VTH67                 , 0x48 },
1419         { STB0899_VTH78                 , 0x38 },
1420         { STB0899_PRVIT                 , 0xff },
1421         { STB0899_VITSYNC               , 0x19 },
1422         { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1423         { STB0899_TSULC                 , 0x42 },
1424         { STB0899_RSLLC                 , 0x40 },
1425         { STB0899_TSLPL                 , 0x12 },
1426         { STB0899_TSCFGH                , 0x0c },
1427         { STB0899_TSCFGM                , 0x00 },
1428         { STB0899_TSCFGL                , 0x0c },
1429         { STB0899_TSOUT                 , 0x0d }, /* 0x0d for CAM */
1430         { STB0899_RSSYNCDEL             , 0x00 },
1431         { STB0899_TSINHDELH             , 0x02 },
1432         { STB0899_TSINHDELM             , 0x00 },
1433         { STB0899_TSINHDELL             , 0x00 },
1434         { STB0899_TSLLSTKM              , 0x00 },
1435         { STB0899_TSLLSTKL              , 0x00 },
1436         { STB0899_TSULSTKM              , 0x00 },
1437         { STB0899_TSULSTKL              , 0xab },
1438         { STB0899_PCKLENUL              , 0x00 },
1439         { STB0899_PCKLENLL              , 0xcc },
1440         { STB0899_RSPCKLEN              , 0xcc },
1441         { STB0899_TSSTATUS              , 0x80 },
1442         { STB0899_ERRCTRL1              , 0xb6 },
1443         { STB0899_ERRCTRL2              , 0x96 },
1444         { STB0899_ERRCTRL3              , 0x89 },
1445         { STB0899_DMONMSK1              , 0x27 },
1446         { STB0899_DMONMSK0              , 0x03 },
1447         { STB0899_DEMAPVIT              , 0x5c },
1448         { STB0899_PLPARM                , 0x1f },
1449         { STB0899_PDELCTRL              , 0x48 },
1450         { STB0899_PDELCTRL2             , 0x00 },
1451         { STB0899_BBHCTRL1              , 0x00 },
1452         { STB0899_BBHCTRL2              , 0x00 },
1453         { STB0899_HYSTTHRESH            , 0x77 },
1454         { STB0899_MATCSTM               , 0x00 },
1455         { STB0899_MATCSTL               , 0x00 },
1456         { STB0899_UPLCSTM               , 0x00 },
1457         { STB0899_UPLCSTL               , 0x00 },
1458         { STB0899_DFLCSTM               , 0x00 },
1459         { STB0899_DFLCSTL               , 0x00 },
1460         { STB0899_SYNCCST               , 0x00 },
1461         { STB0899_SYNCDCSTM             , 0x00 },
1462         { STB0899_SYNCDCSTL             , 0x00 },
1463         { STB0899_ISI_ENTRY             , 0x00 },
1464         { STB0899_ISI_BIT_EN            , 0x00 },
1465         { STB0899_MATSTRM               , 0x00 },
1466         { STB0899_MATSTRL               , 0x00 },
1467         { STB0899_UPLSTRM               , 0x00 },
1468         { STB0899_UPLSTRL               , 0x00 },
1469         { STB0899_DFLSTRM               , 0x00 },
1470         { STB0899_DFLSTRL               , 0x00 },
1471         { STB0899_SYNCSTR               , 0x00 },
1472         { STB0899_SYNCDSTRM             , 0x00 },
1473         { STB0899_SYNCDSTRL             , 0x00 },
1474         { STB0899_CFGPDELSTATUS1        , 0x10 },
1475         { STB0899_CFGPDELSTATUS2        , 0x00 },
1476         { STB0899_BBFERRORM             , 0x00 },
1477         { STB0899_BBFERRORL             , 0x00 },
1478         { STB0899_UPKTERRORM            , 0x00 },
1479         { STB0899_UPKTERRORL            , 0x00 },
1480         { 0xffff                        , 0xff },
1481 };
1482
1483 static const struct stb0899_s2_reg tt3200_stb0899_s2_init_4[] = {
1484         { STB0899_OFF0_BLOCK_LNGTH      , STB0899_BASE_BLOCK_LNGTH      , 0x00000008 }, /* BLOCKLNGTH   */
1485         { STB0899_OFF0_ROW_STR          , STB0899_BASE_ROW_STR          , 0x000000b4 }, /* ROWSTR       */
1486         { STB0899_OFF0_BN_END_ADDR      , STB0899_BASE_BN_END_ADDR      , 0x000004b5 }, /* BNANDADDR    */
1487         { STB0899_OFF0_CN_END_ADDR      , STB0899_BASE_CN_END_ADDR      , 0x00000b4b }, /* CNANDADDR    */
1488         { STB0899_OFF0_INFO_LENGTH      , STB0899_BASE_INFO_LENGTH      , 0x00000078 }, /* INFOLENGTH   */
1489         { STB0899_OFF0_BOT_ADDR         , STB0899_BASE_BOT_ADDR         , 0x000001e0 }, /* BOT_ADDR     */
1490         { STB0899_OFF0_BCH_BLK_LN       , STB0899_BASE_BCH_BLK_LN       , 0x0000a8c0 }, /* BCHBLKLN     */
1491         { STB0899_OFF0_BCH_T            , STB0899_BASE_BCH_T            , 0x0000000c }, /* BCHT         */
1492         { STB0899_OFF0_CNFG_MODE        , STB0899_BASE_CNFG_MODE        , 0x00000001 }, /* CNFGMODE     */
1493         { STB0899_OFF0_LDPC_STAT        , STB0899_BASE_LDPC_STAT        , 0x0000000d }, /* LDPCSTAT     */
1494         { STB0899_OFF0_ITER_SCALE       , STB0899_BASE_ITER_SCALE       , 0x00000040 }, /* ITERSCALE    */
1495         { STB0899_OFF0_INPUT_MODE       , STB0899_BASE_INPUT_MODE       , 0x00000000 }, /* INPUTMODE    */
1496         { STB0899_OFF0_LDPCDECRST       , STB0899_BASE_LDPCDECRST       , 0x00000000 }, /* LDPCDECRST   */
1497         { STB0899_OFF0_CLK_PER_BYTE_RW  , STB0899_BASE_CLK_PER_BYTE_RW  , 0x00000008 }, /* CLKPERBYTE   */
1498         { STB0899_OFF0_BCH_ERRORS       , STB0899_BASE_BCH_ERRORS       , 0x00000000 }, /* BCHERRORS    */
1499         { STB0899_OFF0_LDPC_ERRORS      , STB0899_BASE_LDPC_ERRORS      , 0x00000000 }, /* LDPCERRORS   */
1500         { STB0899_OFF0_BCH_MODE         , STB0899_BASE_BCH_MODE         , 0x00000000 }, /* BCHMODE      */
1501         { STB0899_OFF0_ERR_ACC_PER      , STB0899_BASE_ERR_ACC_PER      , 0x00000008 }, /* ERRACCPER    */
1502         { STB0899_OFF0_BCH_ERR_ACC      , STB0899_BASE_BCH_ERR_ACC      , 0x00000000 }, /* BCHERRACC    */
1503         { STB0899_OFF0_FEC_TP_SEL       , STB0899_BASE_FEC_TP_SEL       , 0x00000000 }, /* FECTPSEL     */
1504         { 0xffff                        , 0xffffffff                    , 0xffffffff },
1505 };
1506
1507 static const struct stb0899_s1_reg tt3200_stb0899_s1_init_5[] = {
1508         { STB0899_TSTCK         , 0x00 },
1509         { STB0899_TSTRES        , 0x00 },
1510         { STB0899_TSTOUT        , 0x00 },
1511         { STB0899_TSTIN         , 0x00 },
1512         { STB0899_TSTSYS        , 0x00 },
1513         { STB0899_TSTCHIP       , 0x00 },
1514         { STB0899_TSTFREE       , 0x00 },
1515         { STB0899_TSTI2C        , 0x00 },
1516         { STB0899_BITSPEEDM     , 0x00 },
1517         { STB0899_BITSPEEDL     , 0x00 },
1518         { STB0899_TBUSBIT       , 0x00 },
1519         { STB0899_TSTDIS        , 0x00 },
1520         { STB0899_TSTDISRX      , 0x00 },
1521         { STB0899_TSTJETON      , 0x00 },
1522         { STB0899_TSTDCADJ      , 0x00 },
1523         { STB0899_TSTAGC1       , 0x00 },
1524         { STB0899_TSTAGC1N      , 0x00 },
1525         { STB0899_TSTPOLYPH     , 0x00 },
1526         { STB0899_TSTR          , 0x00 },
1527         { STB0899_TSTAGC2       , 0x00 },
1528         { STB0899_TSTCTL1       , 0x00 },
1529         { STB0899_TSTCTL2       , 0x00 },
1530         { STB0899_TSTCTL3       , 0x00 },
1531         { STB0899_TSTDEMAP      , 0x00 },
1532         { STB0899_TSTDEMAP2     , 0x00 },
1533         { STB0899_TSTDEMMON     , 0x00 },
1534         { STB0899_TSTRATE       , 0x00 },
1535         { STB0899_TSTSELOUT     , 0x00 },
1536         { STB0899_TSYNC         , 0x00 },
1537         { STB0899_TSTERR        , 0x00 },
1538         { STB0899_TSTRAM1       , 0x00 },
1539         { STB0899_TSTVSELOUT    , 0x00 },
1540         { STB0899_TSTFORCEIN    , 0x00 },
1541         { STB0899_TSTRS1        , 0x00 },
1542         { STB0899_TSTRS2        , 0x00 },
1543         { STB0899_TSTRS3        , 0x00 },
1544         { STB0899_GHOSTREG      , 0x81 },
1545         { 0xffff                , 0xff },
1546 };
1547
1548 #define TT3200_DVBS2_ESNO_AVE                   3
1549 #define TT3200_DVBS2_ESNO_QUANT                 32
1550 #define TT3200_DVBS2_AVFRAMES_COARSE            10
1551 #define TT3200_DVBS2_AVFRAMES_FINE              20
1552 #define TT3200_DVBS2_MISS_THRESHOLD             6
1553 #define TT3200_DVBS2_UWP_THRESHOLD_ACQ          1125
1554 #define TT3200_DVBS2_UWP_THRESHOLD_TRACK        758
1555 #define TT3200_DVBS2_UWP_THRESHOLD_SOF          1350
1556 #define TT3200_DVBS2_SOF_SEARCH_TIMEOUT         1664100
1557
1558 #define TT3200_DVBS2_BTR_NCO_BITS               28
1559 #define TT3200_DVBS2_BTR_GAIN_SHIFT_OFFSET      15
1560 #define TT3200_DVBS2_CRL_NCO_BITS               30
1561 #define TT3200_DVBS2_LDPC_MAX_ITER              70
1562
1563 static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
1564 {
1565         struct dvb_frontend_ops *frontend_ops = NULL;
1566         struct dvb_tuner_ops    *tuner_ops = NULL;
1567         struct tuner_state      t_state;
1568         int err = 0;
1569
1570         if (&fe->ops)
1571                 frontend_ops = &fe->ops;
1572         if (&frontend_ops->tuner_ops)
1573                 tuner_ops = &frontend_ops->tuner_ops;
1574         if (tuner_ops->get_state) {
1575                 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
1576                         printk("%s: Invalid parameter\n", __func__);
1577                         return err;
1578                 }
1579                 *frequency = t_state.frequency;
1580                 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
1581         }
1582         return 0;
1583 }
1584
1585 static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
1586 {
1587         struct dvb_frontend_ops *frontend_ops = NULL;
1588         struct dvb_tuner_ops    *tuner_ops = NULL;
1589         struct tuner_state      t_state;
1590         int err = 0;
1591
1592         t_state.frequency = frequency;
1593         if (&fe->ops)
1594                 frontend_ops = &fe->ops;
1595         if (&frontend_ops->tuner_ops)
1596                 tuner_ops = &frontend_ops->tuner_ops;
1597         if (tuner_ops->set_state) {
1598                 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
1599                         printk("%s: Invalid parameter\n", __func__);
1600                         return err;
1601                 }
1602         }
1603         printk("%s: Frequency=%d\n", __func__, t_state.frequency);
1604         return 0;
1605 }
1606
1607 static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
1608 {
1609         struct dvb_frontend_ops *frontend_ops = &fe->ops;
1610         struct dvb_tuner_ops    *tuner_ops = &frontend_ops->tuner_ops;
1611         struct tuner_state      t_state;
1612         int err = 0;
1613
1614         if (&fe->ops)
1615                 frontend_ops = &fe->ops;
1616         if (&frontend_ops->tuner_ops)
1617                 tuner_ops = &frontend_ops->tuner_ops;
1618         if (tuner_ops->get_state) {
1619                 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
1620                         printk("%s: Invalid parameter\n", __func__);
1621                         return err;
1622                 }
1623                 *bandwidth = t_state.bandwidth;
1624         }
1625         printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
1626         return 0;
1627 }
1628
1629 static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
1630 {
1631         struct dvb_frontend_ops *frontend_ops = NULL;
1632         struct dvb_tuner_ops    *tuner_ops = NULL;
1633         struct tuner_state      t_state;
1634         int err = 0;
1635
1636         t_state.bandwidth = bandwidth;
1637         if (&fe->ops)
1638                 frontend_ops = &fe->ops;
1639         if (&frontend_ops->tuner_ops)
1640                 tuner_ops = &frontend_ops->tuner_ops;
1641         if (tuner_ops->set_state) {
1642                 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
1643                         printk("%s: Invalid parameter\n", __func__);
1644                         return err;
1645                 }
1646         }
1647         printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
1648         return 0;
1649 }
1650
1651 static struct stb0899_config tt3200_config = {
1652         .init_dev               = tt3200_stb0899_s1_init_1,
1653         .init_s2_demod          = tt3200_stb0899_s2_init_2,
1654         .init_s1_demod          = tt3200_stb0899_s1_init_3,
1655         .init_s2_fec            = tt3200_stb0899_s2_init_4,
1656         .init_tst               = tt3200_stb0899_s1_init_5,
1657
1658         .demod_address          = 0x68,
1659
1660         .xtal_freq              = 27000000,
1661         .inversion              = IQ_SWAP_ON, /* 1 */
1662
1663         .esno_ave               = TT3200_DVBS2_ESNO_AVE,
1664         .esno_quant             = TT3200_DVBS2_ESNO_QUANT,
1665         .avframes_coarse        = TT3200_DVBS2_AVFRAMES_COARSE,
1666         .avframes_fine          = TT3200_DVBS2_AVFRAMES_FINE,
1667         .miss_threshold         = TT3200_DVBS2_MISS_THRESHOLD,
1668         .uwp_threshold_acq      = TT3200_DVBS2_UWP_THRESHOLD_ACQ,
1669         .uwp_threshold_track    = TT3200_DVBS2_UWP_THRESHOLD_TRACK,
1670         .uwp_threshold_sof      = TT3200_DVBS2_UWP_THRESHOLD_SOF,
1671         .sof_search_timeout     = TT3200_DVBS2_SOF_SEARCH_TIMEOUT,
1672
1673         .btr_nco_bits           = TT3200_DVBS2_BTR_NCO_BITS,
1674         .btr_gain_shift_offset  = TT3200_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1675         .crl_nco_bits           = TT3200_DVBS2_CRL_NCO_BITS,
1676         .ldpc_max_iter          = TT3200_DVBS2_LDPC_MAX_ITER,
1677
1678         .tuner_get_frequency    = stb6100_get_frequency,
1679         .tuner_set_frequency    = stb6100_set_frequency,
1680         .tuner_set_bandwidth    = stb6100_set_bandwidth,
1681         .tuner_get_bandwidth    = stb6100_get_bandwidth,
1682         .tuner_set_rfsiggain    = NULL,
1683 };
1684
1685 struct stb6100_config tt3200_stb6100_config = {
1686         .tuner_address = 0x60
1687 };
1688
1689 static void frontend_init(struct budget_ci *budget_ci)
1690 {
1691         switch (budget_ci->budget.dev->pci->subsystem_device) {
1692         case 0x100c:            // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
1693                 budget_ci->budget.dvb_frontend =
1694                         dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
1695                 if (budget_ci->budget.dvb_frontend) {
1696                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
1697                         budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1698                         break;
1699                 }
1700                 break;
1701
1702         case 0x100f:            // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
1703                 budget_ci->budget.dvb_frontend =
1704                         dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
1705                 if (budget_ci->budget.dvb_frontend) {
1706                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
1707                         break;
1708                 }
1709                 break;
1710
1711         case 0x1010:            // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
1712                 budget_ci->tuner_pll_address = 0x61;
1713                 budget_ci->budget.dvb_frontend =
1714                         dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1715                 if (budget_ci->budget.dvb_frontend) {
1716                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1717                         break;
1718                 }
1719                 break;
1720
1721         case 0x1011:            // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
1722                 budget_ci->tuner_pll_address = 0x63;
1723                 budget_ci->budget.dvb_frontend =
1724                         dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1725                 if (budget_ci->budget.dvb_frontend) {
1726                         budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1727                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1728                         break;
1729                 }
1730                 break;
1731
1732         case 0x1012:            // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
1733                 budget_ci->tuner_pll_address = 0x60;
1734                 budget_ci->budget.dvb_frontend =
1735                         dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
1736                 if (budget_ci->budget.dvb_frontend) {
1737                         budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1738                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1739                         break;
1740                 }
1741                 break;
1742
1743         case 0x1017:            // TT S-1500 PCI
1744                 budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
1745                 if (budget_ci->budget.dvb_frontend) {
1746                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
1747                         budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1748
1749                         budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
1750                         if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
1751                                 printk("%s: No LNBP21 found!\n", __func__);
1752                                 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1753                                 budget_ci->budget.dvb_frontend = NULL;
1754                         }
1755                 }
1756                 break;
1757
1758         case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
1759                 budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
1760                 if (budget_ci->budget.dvb_frontend) {
1761                         if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) {
1762                                 printk(KERN_ERR "%s: No tda827x found!\n", __func__);
1763                                 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1764                                 budget_ci->budget.dvb_frontend = NULL;
1765                         }
1766                 }
1767                 break;
1768
1769         case 0x1019:            // TT S2-3200 PCI
1770                 budget_ci->budget.dvb_frontend = stb0899_attach(&tt3200_config, &budget_ci->budget.i2c_adap);
1771                 if (budget_ci->budget.dvb_frontend) {
1772                         if (stb6100_attach(budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
1773                                 if (!lnbp21_attach(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1774                                         printk("%s: No LNBP21 found!\n", __FUNCTION__);
1775                                         if (budget_ci->budget.dvb_frontend->ops.tuner_ops.release)
1776                                                 budget_ci->budget.dvb_frontend->ops.tuner_ops.release(budget_ci->budget.dvb_frontend);
1777                                         if (budget_ci->budget.dvb_frontend->ops.release)
1778                                                 budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend);
1779                                         budget_ci->budget.dvb_frontend = NULL;
1780                                 }
1781                         } else {
1782                                 if (budget_ci->budget.dvb_frontend->ops.release)
1783                                         budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend);
1784                         }
1785                 }
1786                 break;
1787
1788         }
1789
1790         if (budget_ci->budget.dvb_frontend == NULL) {
1791                 printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1792                        budget_ci->budget.dev->pci->vendor,
1793                        budget_ci->budget.dev->pci->device,
1794                        budget_ci->budget.dev->pci->subsystem_vendor,
1795                        budget_ci->budget.dev->pci->subsystem_device);
1796         } else {
1797                 if (dvb_register_frontend
1798                     (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
1799                         printk("budget-ci: Frontend registration failed!\n");
1800                         dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1801                         budget_ci->budget.dvb_frontend = NULL;
1802                 }
1803         }
1804 }
1805
1806 static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1807 {
1808         struct budget_ci *budget_ci;
1809         int err;
1810
1811         budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
1812         if (!budget_ci) {
1813                 err = -ENOMEM;
1814                 goto out1;
1815         }
1816
1817         dprintk(2, "budget_ci: %p\n", budget_ci);
1818
1819         dev->ext_priv = budget_ci;
1820
1821         err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
1822                                 adapter_nr);
1823         if (err)
1824                 goto out2;
1825
1826         err = msp430_ir_init(budget_ci);
1827         if (err)
1828                 goto out3;
1829
1830         ciintf_init(budget_ci);
1831
1832         budget_ci->budget.dvb_adapter.priv = budget_ci;
1833         frontend_init(budget_ci);
1834
1835         ttpci_budget_init_hooks(&budget_ci->budget);
1836
1837         return 0;
1838
1839 out3:
1840         ttpci_budget_deinit(&budget_ci->budget);
1841 out2:
1842         kfree(budget_ci);
1843 out1:
1844         return err;
1845 }
1846
1847 static int budget_ci_detach(struct saa7146_dev *dev)
1848 {
1849         struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
1850         struct saa7146_dev *saa = budget_ci->budget.dev;
1851         int err;
1852
1853         if (budget_ci->budget.ci_present)
1854                 ciintf_deinit(budget_ci);
1855         msp430_ir_deinit(budget_ci);
1856         if (budget_ci->budget.dvb_frontend) {
1857                 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
1858                 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1859         }
1860         err = ttpci_budget_deinit(&budget_ci->budget);
1861
1862         // disable frontend and CI interface
1863         saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1864
1865         kfree(budget_ci);
1866
1867         return err;
1868 }
1869
1870 static struct saa7146_extension budget_extension;
1871
1872 MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
1873 MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1874 MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T  PCI", BUDGET_TT);
1875 MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1876 MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1877 MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1878 MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1879
1880 static struct pci_device_id pci_tbl[] = {
1881         MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
1882         MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
1883         MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
1884         MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
1885         MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
1886         MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1887         MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1888         MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1889         {
1890          .vendor = 0,
1891          }
1892 };
1893
1894 MODULE_DEVICE_TABLE(pci, pci_tbl);
1895
1896 static struct saa7146_extension budget_extension = {
1897         .name = "budget_ci dvb",
1898         .flags = SAA7146_USE_I2C_IRQ,
1899
1900         .module = THIS_MODULE,
1901         .pci_tbl = &pci_tbl[0],
1902         .attach = budget_ci_attach,
1903         .detach = budget_ci_detach,
1904
1905         .irq_mask = MASK_03 | MASK_06 | MASK_10,
1906         .irq_func = budget_ci_irq,
1907 };
1908
1909 static int __init budget_ci_init(void)
1910 {
1911         return saa7146_register_extension(&budget_extension);
1912 }
1913
1914 static void __exit budget_ci_exit(void)
1915 {
1916         saa7146_unregister_extension(&budget_extension);
1917 }
1918
1919 module_init(budget_ci_init);
1920 module_exit(budget_ci_exit);
1921
1922 MODULE_LICENSE("GPL");
1923 MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1924 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1925                    "budget PCI DVB cards w/ CI-module produced by "
1926                    "Siemens, Technotrend, Hauppauge");