2 * budget-ci.c: driver for the SAA7146 based Budget DVB cards
4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
6 * msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
7 * partially based on the Siemens DVB driver by Ralph+Marcus Metzler
9 * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
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.
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.
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
29 * the project's page is at http://www.linuxtv.org/dvb/
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>
42 #include "dvb_ca_en50221.h"
46 #include "stb0899_drv.h"
47 #include "stb0899_reg.h"
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
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
68 #define CICONTROL_RESET 0x01
69 #define CICONTROL_ENABLETS 0x02
70 #define CICONTROL_CAMDETECT 0x08
72 #define DEBICICTL 0x00420000
73 #define DEBICICAM 0x02420000
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)
82 * Milliseconds during which a key is regarded as pressed.
83 * If an identical command arrives within this time, the timer will start over.
85 #define IR_KEYPRESS_TIMEOUT 250
87 /* RC5 device wildcard */
88 #define IR_DEVICE_ANY 255
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)");
95 module_param(ir_debug, int, 0644);
96 MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
98 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
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 */
106 struct ir_input_state state;
114 struct budget budget;
115 struct tasklet_struct ciintf_irq_tasklet;
118 struct dvb_ca_en50221 ca;
119 struct budget_ci_ir ir;
120 u8 tuner_pll_address; /* used for philips_tdm1316l configs */
123 static void msp430_ir_keyup(unsigned long data)
125 struct budget_ci_ir *ir = (struct budget_ci_ir *) data;
126 ir_input_nokey(ir->dev, &ir->state);
129 static void msp430_ir_interrupt(unsigned long data)
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;
137 * The msp430 chip can generate two different bytes, command and device
139 * type1: X1CCCCCC, C = command bits (0 - 63)
140 * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
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.
148 * Only when we have a command and device byte, a keypress is
153 printk("budget_ci: received byte 0x%02x\n", command);
155 /* Remove repeat bit, we use every command */
156 command = command & 0x7f;
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;
165 /* It's a RC5 device byte */
166 if (!budget_ci->ir.have_command)
168 budget_ci->ir.have_command = false;
170 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
171 budget_ci->ir.rc5_device != (command & 0x1f))
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;
183 mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT));
186 static int msp430_ir_init(struct budget_ci *budget_ci)
188 struct saa7146_dev *saa = budget_ci->budget.dev;
189 struct input_dev *input_dev = budget_ci->ir.dev;
192 budget_ci->ir.dev = input_dev = input_allocate_device();
194 printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
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));
204 input_dev->name = budget_ci->ir.name;
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;
213 input_dev->id.vendor = saa->pci->vendor;
214 input_dev->id.product = saa->pci->device;
216 input_dev->dev.parent = &saa->pci->dev;
218 /* Select keymap and address */
219 switch (budget_ci->budget.dev->pci->subsystem_device) {
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);
229 budget_ci->ir.rc5_device = 0x1f;
231 budget_ci->ir.rc5_device = rc5_device;
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);
241 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
243 budget_ci->ir.rc5_device = rc5_device;
247 ir_input_init(input_dev, &budget_ci->ir.state,
248 IR_TYPE_RC5, ir_codes_budget_ci_old);
251 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
253 budget_ci->ir.rc5_device = rc5_device;
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);
264 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
268 /* note: these must be after input_register_device */
269 input_dev->rep[REP_DELAY] = 400;
270 input_dev->rep[REP_PERIOD] = 250;
272 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
273 (unsigned long) budget_ci);
275 SAA7146_IER_ENABLE(saa, MASK_06);
276 saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
281 input_free_device(input_dev);
286 static void msp430_ir_deinit(struct budget_ci *budget_ci)
288 struct saa7146_dev *saa = budget_ci->budget.dev;
289 struct input_dev *dev = budget_ci->ir.dev;
291 SAA7146_IER_DISABLE(saa, MASK_06);
292 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
293 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
295 del_timer_sync(&dev->timer);
296 ir_input_nokey(dev, &budget_ci->ir.state);
298 input_unregister_device(dev);
301 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
303 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
308 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
309 DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
312 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
314 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
319 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
320 DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
323 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
325 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
330 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
331 DEBIADDR_IO | (address & 3), 1, 1, 0);
334 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
336 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
341 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
342 DEBIADDR_IO | (address & 3), 1, value, 1, 0);
345 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
347 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
348 struct saa7146_dev *saa = budget_ci->budget.dev;
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);
357 budget_ci->slot_status = SLOTSTATUS_RESET;
358 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
360 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
361 CICONTROL_RESET, 1, 0);
363 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
364 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
368 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
370 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
371 struct saa7146_dev *saa = budget_ci->budget.dev;
376 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
377 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
381 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
383 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
384 struct saa7146_dev *saa = budget_ci->budget.dev;
390 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
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);
396 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
400 static void ciintf_interrupt(unsigned long data)
402 struct budget_ci *budget_ci = (struct budget_ci *) data;
403 struct saa7146_dev *saa = budget_ci->budget.dev;
406 // ensure we don't get spurious IRQs during initialisation
407 if (!budget_ci->budget.ci_present)
410 // read the CAM status
411 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
412 if (flags & CICONTROL_CAMDETECT) {
414 // GPIO should be set to trigger on falling edge if a CAM is present
415 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
417 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
419 budget_ci->slot_status = SLOTSTATUS_PRESENT;
420 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
421 DVB_CA_EN50221_CAMCHANGE_INSERTED);
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);
428 } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
430 dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
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);
439 // generate a CAM removal IRQ if we haven't already
440 if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
442 budget_ci->slot_status = SLOTSTATUS_NONE;
443 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
444 DVB_CA_EN50221_CAMCHANGE_REMOVED);
449 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
451 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
454 // ensure we don't get spurious IRQs during initialisation
455 if (!budget_ci->budget.ci_present)
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;
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;
473 budget_ci->slot_status = SLOTSTATUS_NONE;
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;
480 return DVB_CA_EN50221_POLL_CAM_PRESENT;
486 static int ciintf_init(struct budget_ci *budget_ci)
488 struct saa7146_dev *saa = budget_ci->budget.dev;
494 memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
497 saa7146_write(saa, MC1, MASK_27 | MASK_11);
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) {
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;
512 // version 0xa2 of the CI firmware doesn't generate interrupts
513 if (ci_version == 0xa2) {
515 budget_ci->ci_irq = 0;
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;
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,
536 ca_flags, 1)) != 0) {
537 printk("budget_ci: CI interface detected, but initialisation failed.\n");
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);
547 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
549 SAA7146_IER_ENABLE(saa, MASK_03);
553 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
554 CICONTROL_RESET, 1, 0);
557 printk("budget_ci: CI interface initialised\n");
558 budget_ci->budget.ci_present = 1;
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);
571 saa7146_write(saa, MC1, MASK_27);
575 static void ciintf_deinit(struct budget_ci *budget_ci)
577 struct saa7146_dev *saa = budget_ci->budget.dev;
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);
587 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
589 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
590 CICONTROL_RESET, 1, 0);
592 // disable TS data stream to CI interface
593 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
595 // release the CA device
596 dvb_ca_en50221_release(&budget_ci->ca);
599 saa7146_write(saa, MC1, MASK_27);
602 static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
604 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
606 dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
609 tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
612 ttpci_budget_irq10_handler(dev, isr);
614 if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
615 tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
618 static u8 philips_su1278_tt_inittab[] = {
664 static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
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);
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);
684 stv0299_writereg(fe, 0x0e, 0x23);
685 stv0299_writereg(fe, 0x0f, 0x94);
686 stv0299_writereg(fe, 0x10, 0x39);
687 stv0299_writereg(fe, 0x15, 0xc9);
689 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
690 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
691 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
696 static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe,
697 struct dvb_frontend_parameters *params)
699 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
702 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
704 if ((params->frequency < 950000) || (params->frequency > 2150000))
707 div = (params->frequency + (500 - 1)) / 500; // round correctly
708 buf[0] = (div >> 8) & 0x7f;
710 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
713 if (params->u.qpsk.symbol_rate < 4000000)
716 if (params->frequency < 1250000)
718 else if (params->frequency < 1550000)
720 else if (params->frequency < 2050000)
722 else if (params->frequency < 2150000)
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)
732 static struct stv0299_config philips_su1278_tt_config = {
734 .demod_address = 0x68,
735 .inittab = philips_su1278_tt_inittab,
739 .lock_output = STV0299_LOCKOUTPUT_1,
740 .volt13_op0_op1 = STV0299_VOLT13_OP1,
742 .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
747 static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
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) };
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)
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);
777 static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
779 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
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;
785 // determine charge pump
786 tuner_frequency = params->frequency + 36130000;
787 if (tuner_frequency < 87000000)
789 else if (tuner_frequency < 130000000)
791 else if (tuner_frequency < 160000000)
793 else if (tuner_frequency < 200000000)
795 else if (tuner_frequency < 290000000)
797 else if (tuner_frequency < 420000000)
799 else if (tuner_frequency < 480000000)
801 else if (tuner_frequency < 620000000)
803 else if (tuner_frequency < 830000000)
805 else if (tuner_frequency < 895000000)
811 if (params->frequency < 49000000)
813 else if (params->frequency < 159000000)
815 else if (params->frequency < 444000000)
817 else if (params->frequency < 861000000)
822 // setup PLL filter and TDA9889
823 switch (params->u.ofdm.bandwidth) {
824 case BANDWIDTH_6_MHZ:
825 tda1004x_writereg(fe, 0x0C, 0x14);
829 case BANDWIDTH_7_MHZ:
830 tda1004x_writereg(fe, 0x0C, 0x80);
834 case BANDWIDTH_8_MHZ:
835 tda1004x_writereg(fe, 0x0C, 0x14);
844 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
845 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
847 // setup tuner buffer
848 tuner_buf[0] = tuner_frequency >> 8;
849 tuner_buf[1] = tuner_frequency & 0xff;
851 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
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)
862 static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
863 const struct firmware **fw, char *name)
865 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
867 return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
870 static struct tda1004x_config philips_tdm1316l_config = {
872 .demod_address = 0x8,
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,
881 static struct tda1004x_config philips_tdm1316l_config_invert = {
883 .demod_address = 0x8,
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,
892 static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
894 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
896 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
899 .len = sizeof(tuner_buf) };
900 int tuner_frequency = 0;
903 // determine charge pump
904 tuner_frequency = params->frequency + 36125000;
905 if (tuner_frequency < 87000000)
907 else if (tuner_frequency < 130000000) {
910 } else if (tuner_frequency < 160000000) {
913 } else if (tuner_frequency < 200000000) {
916 } else if (tuner_frequency < 290000000) {
919 } else if (tuner_frequency < 420000000) {
922 } else if (tuner_frequency < 480000000) {
925 } else if (tuner_frequency < 620000000) {
928 } else if (tuner_frequency < 830000000) {
931 } else if (tuner_frequency < 895000000) {
937 // assume PLL filter should always be 8MHz for the moment.
941 tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500;
943 // setup tuner buffer
944 tuner_buf[0] = tuner_frequency >> 8;
945 tuner_buf[1] = tuner_frequency & 0xff;
947 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
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)
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)
967 static u8 dvbc_philips_tdm1316l_inittab[] = {
1060 static struct stv0297_config dvbc_philips_tdm1316l_config = {
1061 .demod_address = 0x1c,
1062 .inittab = dvbc_philips_tdm1316l_inittab,
1064 .stop_during_read = 1,
1067 static struct tda10023_config tda10023_config = {
1068 .demod_address = 0xc,
1077 /* TT S2-3200 DVB-S (STB0899) Inittab */
1078 static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
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 },
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 , 0x48 }, /* 12k Pullup */
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 },
1167 static const struct stb0899_s2_reg tt3200_stb0899_s2_init_2[] = {
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 */
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 */
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 },
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 },
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 },
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 },
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
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
1563 static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
1565 struct dvb_frontend_ops *frontend_ops = NULL;
1566 struct dvb_tuner_ops *tuner_ops = NULL;
1567 struct tuner_state t_state;
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__);
1579 *frequency = t_state.frequency;
1580 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
1585 static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
1587 struct dvb_frontend_ops *frontend_ops = NULL;
1588 struct dvb_tuner_ops *tuner_ops = NULL;
1589 struct tuner_state t_state;
1592 t_state.frequency = frequency;
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__);
1603 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
1607 static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
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;
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__);
1623 *bandwidth = t_state.bandwidth;
1625 printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
1629 static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
1631 struct dvb_frontend_ops *frontend_ops = NULL;
1632 struct dvb_tuner_ops *tuner_ops = NULL;
1633 struct tuner_state t_state;
1636 t_state.bandwidth = bandwidth;
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__);
1647 printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
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,
1658 .demod_address = 0x68,
1660 .xtal_freq = 27000000,
1661 .inversion = IQ_SWAP_ON, /* 1 */
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,
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,
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,
1685 struct stb6100_config tt3200_stb6100_config = {
1686 .tuner_address = 0x60,
1687 .refclock = 27000000,
1690 static void frontend_init(struct budget_ci *budget_ci)
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;
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;
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;
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;
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;
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;
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;
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;
1770 case 0x1019: // TT S2-3200 PCI
1772 * NOTE! on some STB0899 versions, the internal PLL takes a longer time
1773 * to settle, aka LOCK. On the older revisions of the chip, we don't see
1774 * this, as a result on the newer chips the entire clock tree, will not
1775 * be stable after a freshly POWER 'ed up situation.
1776 * In this case, we should RESET the STB0899 (Active LOW) and wait for
1777 * PLL stabilization.
1779 * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is
1780 * connected to the SAA7146 GPIO, GPIO2, Pin 142
1782 /* Reset Demodulator */
1783 saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
1784 /* Wait for everything to die */
1786 /* Pull it up out of Reset state */
1787 saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
1788 /* Wait for PLL to stabilize */
1791 * PLL state should be stable now. Ideally, we should check
1792 * for PLL LOCK status. But well, never mind!
1794 budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
1795 if (budget_ci->budget.dvb_frontend) {
1796 if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
1797 if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1798 printk("%s: No LNBP21 found!\n", __FUNCTION__);
1799 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1800 budget_ci->budget.dvb_frontend = NULL;
1803 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1804 budget_ci->budget.dvb_frontend = NULL;
1811 if (budget_ci->budget.dvb_frontend == NULL) {
1812 printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1813 budget_ci->budget.dev->pci->vendor,
1814 budget_ci->budget.dev->pci->device,
1815 budget_ci->budget.dev->pci->subsystem_vendor,
1816 budget_ci->budget.dev->pci->subsystem_device);
1818 if (dvb_register_frontend
1819 (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
1820 printk("budget-ci: Frontend registration failed!\n");
1821 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1822 budget_ci->budget.dvb_frontend = NULL;
1827 static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1829 struct budget_ci *budget_ci;
1832 budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
1838 dprintk(2, "budget_ci: %p\n", budget_ci);
1840 dev->ext_priv = budget_ci;
1842 err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
1847 err = msp430_ir_init(budget_ci);
1851 ciintf_init(budget_ci);
1853 budget_ci->budget.dvb_adapter.priv = budget_ci;
1854 frontend_init(budget_ci);
1856 ttpci_budget_init_hooks(&budget_ci->budget);
1861 ttpci_budget_deinit(&budget_ci->budget);
1868 static int budget_ci_detach(struct saa7146_dev *dev)
1870 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
1871 struct saa7146_dev *saa = budget_ci->budget.dev;
1874 if (budget_ci->budget.ci_present)
1875 ciintf_deinit(budget_ci);
1876 msp430_ir_deinit(budget_ci);
1877 if (budget_ci->budget.dvb_frontend) {
1878 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
1879 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1881 err = ttpci_budget_deinit(&budget_ci->budget);
1883 // disable frontend and CI interface
1884 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1891 static struct saa7146_extension budget_extension;
1893 MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
1894 MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1895 MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
1896 MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1897 MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1898 MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1899 MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1901 static struct pci_device_id pci_tbl[] = {
1902 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
1903 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
1904 MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
1905 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
1906 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
1907 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1908 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1909 MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1915 MODULE_DEVICE_TABLE(pci, pci_tbl);
1917 static struct saa7146_extension budget_extension = {
1918 .name = "budget_ci dvb",
1919 .flags = SAA7146_USE_I2C_IRQ,
1921 .module = THIS_MODULE,
1922 .pci_tbl = &pci_tbl[0],
1923 .attach = budget_ci_attach,
1924 .detach = budget_ci_detach,
1926 .irq_mask = MASK_03 | MASK_06 | MASK_10,
1927 .irq_func = budget_ci_irq,
1930 static int __init budget_ci_init(void)
1932 return saa7146_register_extension(&budget_extension);
1935 static void __exit budget_ci_exit(void)
1937 saa7146_unregister_extension(&budget_extension);
1940 module_init(budget_ci_init);
1941 module_exit(budget_ci_exit);
1943 MODULE_LICENSE("GPL");
1944 MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1945 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1946 "budget PCI DVB cards w/ CI-module produced by "
1947 "Siemens, Technotrend, Hauppauge");