V4L/DVB (9417): DVB_ATTACH for STB0899, STB6100, TDA8261
[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         .refclock       = 27000000,
1688 };
1689
1690 static void frontend_init(struct budget_ci *budget_ci)
1691 {
1692         switch (budget_ci->budget.dev->pci->subsystem_device) {
1693         case 0x100c:            // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
1694                 budget_ci->budget.dvb_frontend =
1695                         dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
1696                 if (budget_ci->budget.dvb_frontend) {
1697                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
1698                         budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1699                         break;
1700                 }
1701                 break;
1702
1703         case 0x100f:            // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
1704                 budget_ci->budget.dvb_frontend =
1705                         dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
1706                 if (budget_ci->budget.dvb_frontend) {
1707                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
1708                         break;
1709                 }
1710                 break;
1711
1712         case 0x1010:            // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
1713                 budget_ci->tuner_pll_address = 0x61;
1714                 budget_ci->budget.dvb_frontend =
1715                         dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1716                 if (budget_ci->budget.dvb_frontend) {
1717                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1718                         break;
1719                 }
1720                 break;
1721
1722         case 0x1011:            // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
1723                 budget_ci->tuner_pll_address = 0x63;
1724                 budget_ci->budget.dvb_frontend =
1725                         dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1726                 if (budget_ci->budget.dvb_frontend) {
1727                         budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1728                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1729                         break;
1730                 }
1731                 break;
1732
1733         case 0x1012:            // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
1734                 budget_ci->tuner_pll_address = 0x60;
1735                 budget_ci->budget.dvb_frontend =
1736                         dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
1737                 if (budget_ci->budget.dvb_frontend) {
1738                         budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1739                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1740                         break;
1741                 }
1742                 break;
1743
1744         case 0x1017:            // TT S-1500 PCI
1745                 budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
1746                 if (budget_ci->budget.dvb_frontend) {
1747                         budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
1748                         budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1749
1750                         budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
1751                         if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
1752                                 printk("%s: No LNBP21 found!\n", __func__);
1753                                 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1754                                 budget_ci->budget.dvb_frontend = NULL;
1755                         }
1756                 }
1757                 break;
1758
1759         case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
1760                 budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
1761                 if (budget_ci->budget.dvb_frontend) {
1762                         if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) {
1763                                 printk(KERN_ERR "%s: No tda827x found!\n", __func__);
1764                                 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1765                                 budget_ci->budget.dvb_frontend = NULL;
1766                         }
1767                 }
1768                 break;
1769
1770         case 0x1019:            // TT S2-3200 PCI
1771                 budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
1772                 if (budget_ci->budget.dvb_frontend) {
1773                         if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
1774                                 if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1775                                         printk("%s: No LNBP21 found!\n", __FUNCTION__);
1776                                         dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1777                                         budget_ci->budget.dvb_frontend = NULL;
1778                                 }
1779                         } else {
1780                                         dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1781                                         budget_ci->budget.dvb_frontend = NULL;
1782                         }
1783                 }
1784                 break;
1785
1786         }
1787
1788         if (budget_ci->budget.dvb_frontend == NULL) {
1789                 printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1790                        budget_ci->budget.dev->pci->vendor,
1791                        budget_ci->budget.dev->pci->device,
1792                        budget_ci->budget.dev->pci->subsystem_vendor,
1793                        budget_ci->budget.dev->pci->subsystem_device);
1794         } else {
1795                 if (dvb_register_frontend
1796                     (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
1797                         printk("budget-ci: Frontend registration failed!\n");
1798                         dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1799                         budget_ci->budget.dvb_frontend = NULL;
1800                 }
1801         }
1802 }
1803
1804 static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1805 {
1806         struct budget_ci *budget_ci;
1807         int err;
1808
1809         budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
1810         if (!budget_ci) {
1811                 err = -ENOMEM;
1812                 goto out1;
1813         }
1814
1815         dprintk(2, "budget_ci: %p\n", budget_ci);
1816
1817         dev->ext_priv = budget_ci;
1818
1819         err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
1820                                 adapter_nr);
1821         if (err)
1822                 goto out2;
1823
1824         err = msp430_ir_init(budget_ci);
1825         if (err)
1826                 goto out3;
1827
1828         ciintf_init(budget_ci);
1829
1830         budget_ci->budget.dvb_adapter.priv = budget_ci;
1831         frontend_init(budget_ci);
1832
1833         ttpci_budget_init_hooks(&budget_ci->budget);
1834
1835         return 0;
1836
1837 out3:
1838         ttpci_budget_deinit(&budget_ci->budget);
1839 out2:
1840         kfree(budget_ci);
1841 out1:
1842         return err;
1843 }
1844
1845 static int budget_ci_detach(struct saa7146_dev *dev)
1846 {
1847         struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
1848         struct saa7146_dev *saa = budget_ci->budget.dev;
1849         int err;
1850
1851         if (budget_ci->budget.ci_present)
1852                 ciintf_deinit(budget_ci);
1853         msp430_ir_deinit(budget_ci);
1854         if (budget_ci->budget.dvb_frontend) {
1855                 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
1856                 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1857         }
1858         err = ttpci_budget_deinit(&budget_ci->budget);
1859
1860         // disable frontend and CI interface
1861         saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1862
1863         kfree(budget_ci);
1864
1865         return err;
1866 }
1867
1868 static struct saa7146_extension budget_extension;
1869
1870 MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
1871 MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1872 MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T  PCI", BUDGET_TT);
1873 MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1874 MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1875 MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1876 MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1877
1878 static struct pci_device_id pci_tbl[] = {
1879         MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
1880         MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
1881         MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
1882         MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
1883         MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
1884         MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1885         MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1886         MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1887         {
1888          .vendor = 0,
1889          }
1890 };
1891
1892 MODULE_DEVICE_TABLE(pci, pci_tbl);
1893
1894 static struct saa7146_extension budget_extension = {
1895         .name = "budget_ci dvb",
1896         .flags = SAA7146_USE_I2C_IRQ,
1897
1898         .module = THIS_MODULE,
1899         .pci_tbl = &pci_tbl[0],
1900         .attach = budget_ci_attach,
1901         .detach = budget_ci_detach,
1902
1903         .irq_mask = MASK_03 | MASK_06 | MASK_10,
1904         .irq_func = budget_ci_irq,
1905 };
1906
1907 static int __init budget_ci_init(void)
1908 {
1909         return saa7146_register_extension(&budget_extension);
1910 }
1911
1912 static void __exit budget_ci_exit(void)
1913 {
1914         saa7146_unregister_extension(&budget_extension);
1915 }
1916
1917 module_init(budget_ci_init);
1918 module_exit(budget_ci_exit);
1919
1920 MODULE_LICENSE("GPL");
1921 MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1922 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1923                    "budget PCI DVB cards w/ CI-module produced by "
1924                    "Siemens, Technotrend, Hauppauge");