Merge branch 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[cris-mirror.git] / drivers / media / dvb / ttpci / budget-ci.c
blobb82756db5bd17aa2a870caf1fd4695777acbc3a4
1 /*
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/
32 #include <linux/module.h>
33 #include <linux/errno.h>
34 #include <linux/slab.h>
35 #include <linux/interrupt.h>
36 #include <linux/spinlock.h>
37 #include <media/rc-core.h>
39 #include "budget.h"
41 #include "dvb_ca_en50221.h"
42 #include "stv0299.h"
43 #include "stv0297.h"
44 #include "tda1004x.h"
45 #include "stb0899_drv.h"
46 #include "stb0899_reg.h"
47 #include "stb0899_cfg.h"
48 #include "stb6100.h"
49 #include "stb6100_cfg.h"
50 #include "lnbp21.h"
51 #include "bsbe1.h"
52 #include "bsru6.h"
53 #include "tda1002x.h"
54 #include "tda827x.h"
56 #define MODULE_NAME "budget_ci"
59 * Regarding DEBIADDR_IR:
60 * Some CI modules hang if random addresses are read.
61 * Using address 0x4000 for the IR read means that we
62 * use the same address as for CI version, which should
63 * be a safe default.
65 #define DEBIADDR_IR 0x4000
66 #define DEBIADDR_CICONTROL 0x0000
67 #define DEBIADDR_CIVERSION 0x4000
68 #define DEBIADDR_IO 0x1000
69 #define DEBIADDR_ATTR 0x3000
71 #define CICONTROL_RESET 0x01
72 #define CICONTROL_ENABLETS 0x02
73 #define CICONTROL_CAMDETECT 0x08
75 #define DEBICICTL 0x00420000
76 #define DEBICICAM 0x02420000
78 #define SLOTSTATUS_NONE 1
79 #define SLOTSTATUS_PRESENT 2
80 #define SLOTSTATUS_RESET 4
81 #define SLOTSTATUS_READY 8
82 #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
84 /* RC5 device wildcard */
85 #define IR_DEVICE_ANY 255
87 static int rc5_device = -1;
88 module_param(rc5_device, int, 0644);
89 MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
91 static int ir_debug;
92 module_param(ir_debug, int, 0644);
93 MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
95 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
97 struct budget_ci_ir {
98 struct rc_dev *dev;
99 struct tasklet_struct msp430_irq_tasklet;
100 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
101 char phys[32];
102 int rc5_device;
103 u32 ir_key;
104 bool have_command;
107 struct budget_ci {
108 struct budget budget;
109 struct tasklet_struct ciintf_irq_tasklet;
110 int slot_status;
111 int ci_irq;
112 struct dvb_ca_en50221 ca;
113 struct budget_ci_ir ir;
114 u8 tuner_pll_address; /* used for philips_tdm1316l configs */
117 static void msp430_ir_interrupt(unsigned long data)
119 struct budget_ci *budget_ci = (struct budget_ci *) data;
120 struct rc_dev *dev = budget_ci->ir.dev;
121 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
124 * The msp430 chip can generate two different bytes, command and device
126 * type1: X1CCCCCC, C = command bits (0 - 63)
127 * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
129 * Each signal from the remote control can generate one or more command
130 * bytes and one or more device bytes. For the repeated bytes, the
131 * highest bit (X) is set. The first command byte is always generated
132 * before the first device byte. Other than that, no specific order
133 * seems to apply. To make life interesting, bytes can also be lost.
135 * Only when we have a command and device byte, a keypress is
136 * generated.
139 if (ir_debug)
140 printk("budget_ci: received byte 0x%02x\n", command);
142 /* Remove repeat bit, we use every command */
143 command = command & 0x7f;
145 /* Is this a RC5 command byte? */
146 if (command & 0x40) {
147 budget_ci->ir.have_command = true;
148 budget_ci->ir.ir_key = command & 0x3f;
149 return;
152 /* It's a RC5 device byte */
153 if (!budget_ci->ir.have_command)
154 return;
155 budget_ci->ir.have_command = false;
157 /* FIXME: We should generate complete scancodes with device info */
158 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
159 budget_ci->ir.rc5_device != (command & 0x1f))
160 return;
162 rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
165 static int msp430_ir_init(struct budget_ci *budget_ci)
167 struct saa7146_dev *saa = budget_ci->budget.dev;
168 struct rc_dev *dev;
169 int error;
171 dev = rc_allocate_device();
172 if (!dev) {
173 printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
174 return -ENOMEM;
177 snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
178 "Budget-CI dvb ir receiver %s", saa->name);
179 snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
180 "pci-%s/ir0", pci_name(saa->pci));
182 dev->driver_name = MODULE_NAME;
183 dev->input_name = budget_ci->ir.name;
184 dev->input_phys = budget_ci->ir.phys;
185 dev->input_id.bustype = BUS_PCI;
186 dev->input_id.version = 1;
187 dev->scanmask = 0xff;
188 if (saa->pci->subsystem_vendor) {
189 dev->input_id.vendor = saa->pci->subsystem_vendor;
190 dev->input_id.product = saa->pci->subsystem_device;
191 } else {
192 dev->input_id.vendor = saa->pci->vendor;
193 dev->input_id.product = saa->pci->device;
195 dev->dev.parent = &saa->pci->dev;
197 if (rc5_device < 0)
198 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
199 else
200 budget_ci->ir.rc5_device = rc5_device;
202 /* Select keymap and address */
203 switch (budget_ci->budget.dev->pci->subsystem_device) {
204 case 0x100c:
205 case 0x100f:
206 case 0x1011:
207 case 0x1012:
208 /* The hauppauge keymap is a superset of these remotes */
209 dev->map_name = RC_MAP_HAUPPAUGE_NEW;
211 if (rc5_device < 0)
212 budget_ci->ir.rc5_device = 0x1f;
213 break;
214 case 0x1010:
215 case 0x1017:
216 case 0x1019:
217 case 0x101a:
218 /* for the Technotrend 1500 bundled remote */
219 dev->map_name = RC_MAP_TT_1500;
220 break;
221 default:
222 /* unknown remote */
223 dev->map_name = RC_MAP_BUDGET_CI_OLD;
224 break;
227 error = rc_register_device(dev);
228 if (error) {
229 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
230 rc_free_device(dev);
231 return error;
234 budget_ci->ir.dev = dev;
236 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
237 (unsigned long) budget_ci);
239 SAA7146_IER_ENABLE(saa, MASK_06);
240 saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
242 return 0;
245 static void msp430_ir_deinit(struct budget_ci *budget_ci)
247 struct saa7146_dev *saa = budget_ci->budget.dev;
249 SAA7146_IER_DISABLE(saa, MASK_06);
250 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
251 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
253 rc_unregister_device(budget_ci->ir.dev);
256 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
258 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
260 if (slot != 0)
261 return -EINVAL;
263 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
264 DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
267 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
269 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
271 if (slot != 0)
272 return -EINVAL;
274 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
275 DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
278 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
280 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
282 if (slot != 0)
283 return -EINVAL;
285 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
286 DEBIADDR_IO | (address & 3), 1, 1, 0);
289 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
291 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
293 if (slot != 0)
294 return -EINVAL;
296 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
297 DEBIADDR_IO | (address & 3), 1, value, 1, 0);
300 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
302 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
303 struct saa7146_dev *saa = budget_ci->budget.dev;
305 if (slot != 0)
306 return -EINVAL;
308 if (budget_ci->ci_irq) {
309 // trigger on RISING edge during reset so we know when READY is re-asserted
310 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
312 budget_ci->slot_status = SLOTSTATUS_RESET;
313 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
314 msleep(1);
315 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
316 CICONTROL_RESET, 1, 0);
318 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
319 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
320 return 0;
323 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
325 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
326 struct saa7146_dev *saa = budget_ci->budget.dev;
328 if (slot != 0)
329 return -EINVAL;
331 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
332 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
333 return 0;
336 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
338 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
339 struct saa7146_dev *saa = budget_ci->budget.dev;
340 int tmp;
342 if (slot != 0)
343 return -EINVAL;
345 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
347 tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
348 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
349 tmp | CICONTROL_ENABLETS, 1, 0);
351 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
352 return 0;
355 static void ciintf_interrupt(unsigned long data)
357 struct budget_ci *budget_ci = (struct budget_ci *) data;
358 struct saa7146_dev *saa = budget_ci->budget.dev;
359 unsigned int flags;
361 // ensure we don't get spurious IRQs during initialisation
362 if (!budget_ci->budget.ci_present)
363 return;
365 // read the CAM status
366 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
367 if (flags & CICONTROL_CAMDETECT) {
369 // GPIO should be set to trigger on falling edge if a CAM is present
370 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
372 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
373 // CAM insertion IRQ
374 budget_ci->slot_status = SLOTSTATUS_PRESENT;
375 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
376 DVB_CA_EN50221_CAMCHANGE_INSERTED);
378 } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
379 // CAM ready (reset completed)
380 budget_ci->slot_status = SLOTSTATUS_READY;
381 dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
383 } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
384 // FR/DA IRQ
385 dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
387 } else {
389 // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
390 // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
391 // the CAM might not actually be ready yet.
392 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
394 // generate a CAM removal IRQ if we haven't already
395 if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
396 // CAM removal IRQ
397 budget_ci->slot_status = SLOTSTATUS_NONE;
398 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
399 DVB_CA_EN50221_CAMCHANGE_REMOVED);
404 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
406 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
407 unsigned int flags;
409 // ensure we don't get spurious IRQs during initialisation
410 if (!budget_ci->budget.ci_present)
411 return -EINVAL;
413 // read the CAM status
414 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
415 if (flags & CICONTROL_CAMDETECT) {
416 // mark it as present if it wasn't before
417 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
418 budget_ci->slot_status = SLOTSTATUS_PRESENT;
421 // during a RESET, we check if we can read from IO memory to see when CAM is ready
422 if (budget_ci->slot_status & SLOTSTATUS_RESET) {
423 if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
424 budget_ci->slot_status = SLOTSTATUS_READY;
427 } else {
428 budget_ci->slot_status = SLOTSTATUS_NONE;
431 if (budget_ci->slot_status != SLOTSTATUS_NONE) {
432 if (budget_ci->slot_status & SLOTSTATUS_READY) {
433 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
435 return DVB_CA_EN50221_POLL_CAM_PRESENT;
438 return 0;
441 static int ciintf_init(struct budget_ci *budget_ci)
443 struct saa7146_dev *saa = budget_ci->budget.dev;
444 int flags;
445 int result;
446 int ci_version;
447 int ca_flags;
449 memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
451 // enable DEBI pins
452 saa7146_write(saa, MC1, MASK_27 | MASK_11);
454 // test if it is there
455 ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
456 if ((ci_version & 0xa0) != 0xa0) {
457 result = -ENODEV;
458 goto error;
461 // determine whether a CAM is present or not
462 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
463 budget_ci->slot_status = SLOTSTATUS_NONE;
464 if (flags & CICONTROL_CAMDETECT)
465 budget_ci->slot_status = SLOTSTATUS_PRESENT;
467 // version 0xa2 of the CI firmware doesn't generate interrupts
468 if (ci_version == 0xa2) {
469 ca_flags = 0;
470 budget_ci->ci_irq = 0;
471 } else {
472 ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
473 DVB_CA_EN50221_FLAG_IRQ_FR |
474 DVB_CA_EN50221_FLAG_IRQ_DA;
475 budget_ci->ci_irq = 1;
478 // register CI interface
479 budget_ci->ca.owner = THIS_MODULE;
480 budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
481 budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
482 budget_ci->ca.read_cam_control = ciintf_read_cam_control;
483 budget_ci->ca.write_cam_control = ciintf_write_cam_control;
484 budget_ci->ca.slot_reset = ciintf_slot_reset;
485 budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
486 budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
487 budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
488 budget_ci->ca.data = budget_ci;
489 if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
490 &budget_ci->ca,
491 ca_flags, 1)) != 0) {
492 printk("budget_ci: CI interface detected, but initialisation failed.\n");
493 goto error;
496 // Setup CI slot IRQ
497 if (budget_ci->ci_irq) {
498 tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
499 if (budget_ci->slot_status != SLOTSTATUS_NONE) {
500 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
501 } else {
502 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
504 SAA7146_IER_ENABLE(saa, MASK_03);
507 // enable interface
508 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
509 CICONTROL_RESET, 1, 0);
511 // success!
512 printk("budget_ci: CI interface initialised\n");
513 budget_ci->budget.ci_present = 1;
515 // forge a fake CI IRQ so the CAM state is setup correctly
516 if (budget_ci->ci_irq) {
517 flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
518 if (budget_ci->slot_status != SLOTSTATUS_NONE)
519 flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
520 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
523 return 0;
525 error:
526 saa7146_write(saa, MC1, MASK_27);
527 return result;
530 static void ciintf_deinit(struct budget_ci *budget_ci)
532 struct saa7146_dev *saa = budget_ci->budget.dev;
534 // disable CI interrupts
535 if (budget_ci->ci_irq) {
536 SAA7146_IER_DISABLE(saa, MASK_03);
537 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
538 tasklet_kill(&budget_ci->ciintf_irq_tasklet);
541 // reset interface
542 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
543 msleep(1);
544 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
545 CICONTROL_RESET, 1, 0);
547 // disable TS data stream to CI interface
548 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
550 // release the CA device
551 dvb_ca_en50221_release(&budget_ci->ca);
553 // disable DEBI pins
554 saa7146_write(saa, MC1, MASK_27);
557 static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
559 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
561 dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
563 if (*isr & MASK_06)
564 tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
566 if (*isr & MASK_10)
567 ttpci_budget_irq10_handler(dev, isr);
569 if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
570 tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
573 static u8 philips_su1278_tt_inittab[] = {
574 0x01, 0x0f,
575 0x02, 0x30,
576 0x03, 0x00,
577 0x04, 0x5b,
578 0x05, 0x85,
579 0x06, 0x02,
580 0x07, 0x00,
581 0x08, 0x02,
582 0x09, 0x00,
583 0x0C, 0x01,
584 0x0D, 0x81,
585 0x0E, 0x44,
586 0x0f, 0x14,
587 0x10, 0x3c,
588 0x11, 0x84,
589 0x12, 0xda,
590 0x13, 0x97,
591 0x14, 0x95,
592 0x15, 0xc9,
593 0x16, 0x19,
594 0x17, 0x8c,
595 0x18, 0x59,
596 0x19, 0xf8,
597 0x1a, 0xfe,
598 0x1c, 0x7f,
599 0x1d, 0x00,
600 0x1e, 0x00,
601 0x1f, 0x50,
602 0x20, 0x00,
603 0x21, 0x00,
604 0x22, 0x00,
605 0x23, 0x00,
606 0x28, 0x00,
607 0x29, 0x28,
608 0x2a, 0x14,
609 0x2b, 0x0f,
610 0x2c, 0x09,
611 0x2d, 0x09,
612 0x31, 0x1f,
613 0x32, 0x19,
614 0x33, 0xfc,
615 0x34, 0x93,
616 0xff, 0xff
619 static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
621 stv0299_writereg(fe, 0x0e, 0x44);
622 if (srate >= 10000000) {
623 stv0299_writereg(fe, 0x13, 0x97);
624 stv0299_writereg(fe, 0x14, 0x95);
625 stv0299_writereg(fe, 0x15, 0xc9);
626 stv0299_writereg(fe, 0x17, 0x8c);
627 stv0299_writereg(fe, 0x1a, 0xfe);
628 stv0299_writereg(fe, 0x1c, 0x7f);
629 stv0299_writereg(fe, 0x2d, 0x09);
630 } else {
631 stv0299_writereg(fe, 0x13, 0x99);
632 stv0299_writereg(fe, 0x14, 0x8d);
633 stv0299_writereg(fe, 0x15, 0xce);
634 stv0299_writereg(fe, 0x17, 0x43);
635 stv0299_writereg(fe, 0x1a, 0x1d);
636 stv0299_writereg(fe, 0x1c, 0x12);
637 stv0299_writereg(fe, 0x2d, 0x05);
639 stv0299_writereg(fe, 0x0e, 0x23);
640 stv0299_writereg(fe, 0x0f, 0x94);
641 stv0299_writereg(fe, 0x10, 0x39);
642 stv0299_writereg(fe, 0x15, 0xc9);
644 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
645 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
646 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
648 return 0;
651 static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe,
652 struct dvb_frontend_parameters *params)
654 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
655 u32 div;
656 u8 buf[4];
657 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
659 if ((params->frequency < 950000) || (params->frequency > 2150000))
660 return -EINVAL;
662 div = (params->frequency + (500 - 1)) / 500; // round correctly
663 buf[0] = (div >> 8) & 0x7f;
664 buf[1] = div & 0xff;
665 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
666 buf[3] = 0x20;
668 if (params->u.qpsk.symbol_rate < 4000000)
669 buf[3] |= 1;
671 if (params->frequency < 1250000)
672 buf[3] |= 0;
673 else if (params->frequency < 1550000)
674 buf[3] |= 0x40;
675 else if (params->frequency < 2050000)
676 buf[3] |= 0x80;
677 else if (params->frequency < 2150000)
678 buf[3] |= 0xC0;
680 if (fe->ops.i2c_gate_ctrl)
681 fe->ops.i2c_gate_ctrl(fe, 1);
682 if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
683 return -EIO;
684 return 0;
687 static struct stv0299_config philips_su1278_tt_config = {
689 .demod_address = 0x68,
690 .inittab = philips_su1278_tt_inittab,
691 .mclk = 64000000UL,
692 .invert = 0,
693 .skip_reinit = 1,
694 .lock_output = STV0299_LOCKOUTPUT_1,
695 .volt13_op0_op1 = STV0299_VOLT13_OP1,
696 .min_delay_ms = 50,
697 .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
702 static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
704 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
705 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
706 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
707 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
708 sizeof(td1316_init) };
710 // setup PLL configuration
711 if (fe->ops.i2c_gate_ctrl)
712 fe->ops.i2c_gate_ctrl(fe, 1);
713 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
714 return -EIO;
715 msleep(1);
717 // disable the mc44BC374c (do not check for errors)
718 tuner_msg.addr = 0x65;
719 tuner_msg.buf = disable_mc44BC374c;
720 tuner_msg.len = sizeof(disable_mc44BC374c);
721 if (fe->ops.i2c_gate_ctrl)
722 fe->ops.i2c_gate_ctrl(fe, 1);
723 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
724 if (fe->ops.i2c_gate_ctrl)
725 fe->ops.i2c_gate_ctrl(fe, 1);
726 i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
729 return 0;
732 static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
734 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
735 u8 tuner_buf[4];
736 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
737 int tuner_frequency = 0;
738 u8 band, cp, filter;
740 // determine charge pump
741 tuner_frequency = params->frequency + 36130000;
742 if (tuner_frequency < 87000000)
743 return -EINVAL;
744 else if (tuner_frequency < 130000000)
745 cp = 3;
746 else if (tuner_frequency < 160000000)
747 cp = 5;
748 else if (tuner_frequency < 200000000)
749 cp = 6;
750 else if (tuner_frequency < 290000000)
751 cp = 3;
752 else if (tuner_frequency < 420000000)
753 cp = 5;
754 else if (tuner_frequency < 480000000)
755 cp = 6;
756 else if (tuner_frequency < 620000000)
757 cp = 3;
758 else if (tuner_frequency < 830000000)
759 cp = 5;
760 else if (tuner_frequency < 895000000)
761 cp = 7;
762 else
763 return -EINVAL;
765 // determine band
766 if (params->frequency < 49000000)
767 return -EINVAL;
768 else if (params->frequency < 159000000)
769 band = 1;
770 else if (params->frequency < 444000000)
771 band = 2;
772 else if (params->frequency < 861000000)
773 band = 4;
774 else
775 return -EINVAL;
777 // setup PLL filter and TDA9889
778 switch (params->u.ofdm.bandwidth) {
779 case BANDWIDTH_6_MHZ:
780 tda1004x_writereg(fe, 0x0C, 0x14);
781 filter = 0;
782 break;
784 case BANDWIDTH_7_MHZ:
785 tda1004x_writereg(fe, 0x0C, 0x80);
786 filter = 0;
787 break;
789 case BANDWIDTH_8_MHZ:
790 tda1004x_writereg(fe, 0x0C, 0x14);
791 filter = 1;
792 break;
794 default:
795 return -EINVAL;
798 // calculate divisor
799 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
800 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
802 // setup tuner buffer
803 tuner_buf[0] = tuner_frequency >> 8;
804 tuner_buf[1] = tuner_frequency & 0xff;
805 tuner_buf[2] = 0xca;
806 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
808 if (fe->ops.i2c_gate_ctrl)
809 fe->ops.i2c_gate_ctrl(fe, 1);
810 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
811 return -EIO;
813 msleep(1);
814 return 0;
817 static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
818 const struct firmware **fw, char *name)
820 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
822 return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
825 static struct tda1004x_config philips_tdm1316l_config = {
827 .demod_address = 0x8,
828 .invert = 0,
829 .invert_oclk = 0,
830 .xtal_freq = TDA10046_XTAL_4M,
831 .agc_config = TDA10046_AGC_DEFAULT,
832 .if_freq = TDA10046_FREQ_3617,
833 .request_firmware = philips_tdm1316l_request_firmware,
836 static struct tda1004x_config philips_tdm1316l_config_invert = {
838 .demod_address = 0x8,
839 .invert = 1,
840 .invert_oclk = 0,
841 .xtal_freq = TDA10046_XTAL_4M,
842 .agc_config = TDA10046_AGC_DEFAULT,
843 .if_freq = TDA10046_FREQ_3617,
844 .request_firmware = philips_tdm1316l_request_firmware,
847 static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
849 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
850 u8 tuner_buf[5];
851 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
852 .flags = 0,
853 .buf = tuner_buf,
854 .len = sizeof(tuner_buf) };
855 int tuner_frequency = 0;
856 u8 band, cp, filter;
858 // determine charge pump
859 tuner_frequency = params->frequency + 36125000;
860 if (tuner_frequency < 87000000)
861 return -EINVAL;
862 else if (tuner_frequency < 130000000) {
863 cp = 3;
864 band = 1;
865 } else if (tuner_frequency < 160000000) {
866 cp = 5;
867 band = 1;
868 } else if (tuner_frequency < 200000000) {
869 cp = 6;
870 band = 1;
871 } else if (tuner_frequency < 290000000) {
872 cp = 3;
873 band = 2;
874 } else if (tuner_frequency < 420000000) {
875 cp = 5;
876 band = 2;
877 } else if (tuner_frequency < 480000000) {
878 cp = 6;
879 band = 2;
880 } else if (tuner_frequency < 620000000) {
881 cp = 3;
882 band = 4;
883 } else if (tuner_frequency < 830000000) {
884 cp = 5;
885 band = 4;
886 } else if (tuner_frequency < 895000000) {
887 cp = 7;
888 band = 4;
889 } else
890 return -EINVAL;
892 // assume PLL filter should always be 8MHz for the moment.
893 filter = 1;
895 // calculate divisor
896 tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500;
898 // setup tuner buffer
899 tuner_buf[0] = tuner_frequency >> 8;
900 tuner_buf[1] = tuner_frequency & 0xff;
901 tuner_buf[2] = 0xc8;
902 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
903 tuner_buf[4] = 0x80;
905 if (fe->ops.i2c_gate_ctrl)
906 fe->ops.i2c_gate_ctrl(fe, 1);
907 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
908 return -EIO;
910 msleep(50);
912 if (fe->ops.i2c_gate_ctrl)
913 fe->ops.i2c_gate_ctrl(fe, 1);
914 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
915 return -EIO;
917 msleep(1);
919 return 0;
922 static u8 dvbc_philips_tdm1316l_inittab[] = {
923 0x80, 0x01,
924 0x80, 0x00,
925 0x81, 0x01,
926 0x81, 0x00,
927 0x00, 0x09,
928 0x01, 0x69,
929 0x03, 0x00,
930 0x04, 0x00,
931 0x07, 0x00,
932 0x08, 0x00,
933 0x20, 0x00,
934 0x21, 0x40,
935 0x22, 0x00,
936 0x23, 0x00,
937 0x24, 0x40,
938 0x25, 0x88,
939 0x30, 0xff,
940 0x31, 0x00,
941 0x32, 0xff,
942 0x33, 0x00,
943 0x34, 0x50,
944 0x35, 0x7f,
945 0x36, 0x00,
946 0x37, 0x20,
947 0x38, 0x00,
948 0x40, 0x1c,
949 0x41, 0xff,
950 0x42, 0x29,
951 0x43, 0x20,
952 0x44, 0xff,
953 0x45, 0x00,
954 0x46, 0x00,
955 0x49, 0x04,
956 0x4a, 0x00,
957 0x4b, 0x7b,
958 0x52, 0x30,
959 0x55, 0xae,
960 0x56, 0x47,
961 0x57, 0xe1,
962 0x58, 0x3a,
963 0x5a, 0x1e,
964 0x5b, 0x34,
965 0x60, 0x00,
966 0x63, 0x00,
967 0x64, 0x00,
968 0x65, 0x00,
969 0x66, 0x00,
970 0x67, 0x00,
971 0x68, 0x00,
972 0x69, 0x00,
973 0x6a, 0x02,
974 0x6b, 0x00,
975 0x70, 0xff,
976 0x71, 0x00,
977 0x72, 0x00,
978 0x73, 0x00,
979 0x74, 0x0c,
980 0x80, 0x00,
981 0x81, 0x00,
982 0x82, 0x00,
983 0x83, 0x00,
984 0x84, 0x04,
985 0x85, 0x80,
986 0x86, 0x24,
987 0x87, 0x78,
988 0x88, 0x10,
989 0x89, 0x00,
990 0x90, 0x01,
991 0x91, 0x01,
992 0xa0, 0x04,
993 0xa1, 0x00,
994 0xa2, 0x00,
995 0xb0, 0x91,
996 0xb1, 0x0b,
997 0xc0, 0x53,
998 0xc1, 0x70,
999 0xc2, 0x12,
1000 0xd0, 0x00,
1001 0xd1, 0x00,
1002 0xd2, 0x00,
1003 0xd3, 0x00,
1004 0xd4, 0x00,
1005 0xd5, 0x00,
1006 0xde, 0x00,
1007 0xdf, 0x00,
1008 0x61, 0x38,
1009 0x62, 0x0a,
1010 0x53, 0x13,
1011 0x59, 0x08,
1012 0xff, 0xff,
1015 static struct stv0297_config dvbc_philips_tdm1316l_config = {
1016 .demod_address = 0x1c,
1017 .inittab = dvbc_philips_tdm1316l_inittab,
1018 .invert = 0,
1019 .stop_during_read = 1,
1022 static struct tda10023_config tda10023_config = {
1023 .demod_address = 0xc,
1024 .invert = 0,
1025 .xtal = 16000000,
1026 .pll_m = 11,
1027 .pll_p = 3,
1028 .pll_n = 1,
1029 .deltaf = 0xa511,
1032 static struct tda827x_config tda827x_config = {
1033 .config = 0,
1036 /* TT S2-3200 DVB-S (STB0899) Inittab */
1037 static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
1039 { STB0899_DEV_ID , 0x81 },
1040 { STB0899_DISCNTRL1 , 0x32 },
1041 { STB0899_DISCNTRL2 , 0x80 },
1042 { STB0899_DISRX_ST0 , 0x04 },
1043 { STB0899_DISRX_ST1 , 0x00 },
1044 { STB0899_DISPARITY , 0x00 },
1045 { STB0899_DISFIFO , 0x00 },
1046 { STB0899_DISSTATUS , 0x20 },
1047 { STB0899_DISF22 , 0x8c },
1048 { STB0899_DISF22RX , 0x9a },
1049 { STB0899_SYSREG , 0x0b },
1050 { STB0899_ACRPRESC , 0x11 },
1051 { STB0899_ACRDIV1 , 0x0a },
1052 { STB0899_ACRDIV2 , 0x05 },
1053 { STB0899_DACR1 , 0x00 },
1054 { STB0899_DACR2 , 0x00 },
1055 { STB0899_OUTCFG , 0x00 },
1056 { STB0899_MODECFG , 0x00 },
1057 { STB0899_IRQSTATUS_3 , 0x30 },
1058 { STB0899_IRQSTATUS_2 , 0x00 },
1059 { STB0899_IRQSTATUS_1 , 0x00 },
1060 { STB0899_IRQSTATUS_0 , 0x00 },
1061 { STB0899_IRQMSK_3 , 0xf3 },
1062 { STB0899_IRQMSK_2 , 0xfc },
1063 { STB0899_IRQMSK_1 , 0xff },
1064 { STB0899_IRQMSK_0 , 0xff },
1065 { STB0899_IRQCFG , 0x00 },
1066 { STB0899_I2CCFG , 0x88 },
1067 { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
1068 { STB0899_IOPVALUE5 , 0x00 },
1069 { STB0899_IOPVALUE4 , 0x20 },
1070 { STB0899_IOPVALUE3 , 0xc9 },
1071 { STB0899_IOPVALUE2 , 0x90 },
1072 { STB0899_IOPVALUE1 , 0x40 },
1073 { STB0899_IOPVALUE0 , 0x00 },
1074 { STB0899_GPIO00CFG , 0x82 },
1075 { STB0899_GPIO01CFG , 0x82 },
1076 { STB0899_GPIO02CFG , 0x82 },
1077 { STB0899_GPIO03CFG , 0x82 },
1078 { STB0899_GPIO04CFG , 0x82 },
1079 { STB0899_GPIO05CFG , 0x82 },
1080 { STB0899_GPIO06CFG , 0x82 },
1081 { STB0899_GPIO07CFG , 0x82 },
1082 { STB0899_GPIO08CFG , 0x82 },
1083 { STB0899_GPIO09CFG , 0x82 },
1084 { STB0899_GPIO10CFG , 0x82 },
1085 { STB0899_GPIO11CFG , 0x82 },
1086 { STB0899_GPIO12CFG , 0x82 },
1087 { STB0899_GPIO13CFG , 0x82 },
1088 { STB0899_GPIO14CFG , 0x82 },
1089 { STB0899_GPIO15CFG , 0x82 },
1090 { STB0899_GPIO16CFG , 0x82 },
1091 { STB0899_GPIO17CFG , 0x82 },
1092 { STB0899_GPIO18CFG , 0x82 },
1093 { STB0899_GPIO19CFG , 0x82 },
1094 { STB0899_GPIO20CFG , 0x82 },
1095 { STB0899_SDATCFG , 0xb8 },
1096 { STB0899_SCLTCFG , 0xba },
1097 { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
1098 { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
1099 { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
1100 { STB0899_DIRCLKCFG , 0x82 },
1101 { STB0899_CLKOUT27CFG , 0x7e },
1102 { STB0899_STDBYCFG , 0x82 },
1103 { STB0899_CS0CFG , 0x82 },
1104 { STB0899_CS1CFG , 0x82 },
1105 { STB0899_DISEQCOCFG , 0x20 },
1106 { STB0899_GPIO32CFG , 0x82 },
1107 { STB0899_GPIO33CFG , 0x82 },
1108 { STB0899_GPIO34CFG , 0x82 },
1109 { STB0899_GPIO35CFG , 0x82 },
1110 { STB0899_GPIO36CFG , 0x82 },
1111 { STB0899_GPIO37CFG , 0x82 },
1112 { STB0899_GPIO38CFG , 0x82 },
1113 { STB0899_GPIO39CFG , 0x82 },
1114 { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
1115 { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
1116 { STB0899_FILTCTRL , 0x00 },
1117 { STB0899_SYSCTRL , 0x00 },
1118 { STB0899_STOPCLK1 , 0x20 },
1119 { STB0899_STOPCLK2 , 0x00 },
1120 { STB0899_INTBUFSTATUS , 0x00 },
1121 { STB0899_INTBUFCTRL , 0x0a },
1122 { 0xffff , 0xff },
1125 static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
1126 { STB0899_DEMOD , 0x00 },
1127 { STB0899_RCOMPC , 0xc9 },
1128 { STB0899_AGC1CN , 0x41 },
1129 { STB0899_AGC1REF , 0x10 },
1130 { STB0899_RTC , 0x7a },
1131 { STB0899_TMGCFG , 0x4e },
1132 { STB0899_AGC2REF , 0x34 },
1133 { STB0899_TLSR , 0x84 },
1134 { STB0899_CFD , 0xc7 },
1135 { STB0899_ACLC , 0x87 },
1136 { STB0899_BCLC , 0x94 },
1137 { STB0899_EQON , 0x41 },
1138 { STB0899_LDT , 0xdd },
1139 { STB0899_LDT2 , 0xc9 },
1140 { STB0899_EQUALREF , 0xb4 },
1141 { STB0899_TMGRAMP , 0x10 },
1142 { STB0899_TMGTHD , 0x30 },
1143 { STB0899_IDCCOMP , 0xfb },
1144 { STB0899_QDCCOMP , 0x03 },
1145 { STB0899_POWERI , 0x3b },
1146 { STB0899_POWERQ , 0x3d },
1147 { STB0899_RCOMP , 0x81 },
1148 { STB0899_AGCIQIN , 0x80 },
1149 { STB0899_AGC2I1 , 0x04 },
1150 { STB0899_AGC2I2 , 0xf5 },
1151 { STB0899_TLIR , 0x25 },
1152 { STB0899_RTF , 0x80 },
1153 { STB0899_DSTATUS , 0x00 },
1154 { STB0899_LDI , 0xca },
1155 { STB0899_CFRM , 0xf1 },
1156 { STB0899_CFRL , 0xf3 },
1157 { STB0899_NIRM , 0x2a },
1158 { STB0899_NIRL , 0x05 },
1159 { STB0899_ISYMB , 0x17 },
1160 { STB0899_QSYMB , 0xfa },
1161 { STB0899_SFRH , 0x2f },
1162 { STB0899_SFRM , 0x68 },
1163 { STB0899_SFRL , 0x40 },
1164 { STB0899_SFRUPH , 0x2f },
1165 { STB0899_SFRUPM , 0x68 },
1166 { STB0899_SFRUPL , 0x40 },
1167 { STB0899_EQUAI1 , 0xfd },
1168 { STB0899_EQUAQ1 , 0x04 },
1169 { STB0899_EQUAI2 , 0x0f },
1170 { STB0899_EQUAQ2 , 0xff },
1171 { STB0899_EQUAI3 , 0xdf },
1172 { STB0899_EQUAQ3 , 0xfa },
1173 { STB0899_EQUAI4 , 0x37 },
1174 { STB0899_EQUAQ4 , 0x0d },
1175 { STB0899_EQUAI5 , 0xbd },
1176 { STB0899_EQUAQ5 , 0xf7 },
1177 { STB0899_DSTATUS2 , 0x00 },
1178 { STB0899_VSTATUS , 0x00 },
1179 { STB0899_VERROR , 0xff },
1180 { STB0899_IQSWAP , 0x2a },
1181 { STB0899_ECNT1M , 0x00 },
1182 { STB0899_ECNT1L , 0x00 },
1183 { STB0899_ECNT2M , 0x00 },
1184 { STB0899_ECNT2L , 0x00 },
1185 { STB0899_ECNT3M , 0x00 },
1186 { STB0899_ECNT3L , 0x00 },
1187 { STB0899_FECAUTO1 , 0x06 },
1188 { STB0899_FECM , 0x01 },
1189 { STB0899_VTH12 , 0xf0 },
1190 { STB0899_VTH23 , 0xa0 },
1191 { STB0899_VTH34 , 0x78 },
1192 { STB0899_VTH56 , 0x4e },
1193 { STB0899_VTH67 , 0x48 },
1194 { STB0899_VTH78 , 0x38 },
1195 { STB0899_PRVIT , 0xff },
1196 { STB0899_VITSYNC , 0x19 },
1197 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1198 { STB0899_TSULC , 0x42 },
1199 { STB0899_RSLLC , 0x40 },
1200 { STB0899_TSLPL , 0x12 },
1201 { STB0899_TSCFGH , 0x0c },
1202 { STB0899_TSCFGM , 0x00 },
1203 { STB0899_TSCFGL , 0x0c },
1204 { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */
1205 { STB0899_RSSYNCDEL , 0x00 },
1206 { STB0899_TSINHDELH , 0x02 },
1207 { STB0899_TSINHDELM , 0x00 },
1208 { STB0899_TSINHDELL , 0x00 },
1209 { STB0899_TSLLSTKM , 0x00 },
1210 { STB0899_TSLLSTKL , 0x00 },
1211 { STB0899_TSULSTKM , 0x00 },
1212 { STB0899_TSULSTKL , 0xab },
1213 { STB0899_PCKLENUL , 0x00 },
1214 { STB0899_PCKLENLL , 0xcc },
1215 { STB0899_RSPCKLEN , 0xcc },
1216 { STB0899_TSSTATUS , 0x80 },
1217 { STB0899_ERRCTRL1 , 0xb6 },
1218 { STB0899_ERRCTRL2 , 0x96 },
1219 { STB0899_ERRCTRL3 , 0x89 },
1220 { STB0899_DMONMSK1 , 0x27 },
1221 { STB0899_DMONMSK0 , 0x03 },
1222 { STB0899_DEMAPVIT , 0x5c },
1223 { STB0899_PLPARM , 0x1f },
1224 { STB0899_PDELCTRL , 0x48 },
1225 { STB0899_PDELCTRL2 , 0x00 },
1226 { STB0899_BBHCTRL1 , 0x00 },
1227 { STB0899_BBHCTRL2 , 0x00 },
1228 { STB0899_HYSTTHRESH , 0x77 },
1229 { STB0899_MATCSTM , 0x00 },
1230 { STB0899_MATCSTL , 0x00 },
1231 { STB0899_UPLCSTM , 0x00 },
1232 { STB0899_UPLCSTL , 0x00 },
1233 { STB0899_DFLCSTM , 0x00 },
1234 { STB0899_DFLCSTL , 0x00 },
1235 { STB0899_SYNCCST , 0x00 },
1236 { STB0899_SYNCDCSTM , 0x00 },
1237 { STB0899_SYNCDCSTL , 0x00 },
1238 { STB0899_ISI_ENTRY , 0x00 },
1239 { STB0899_ISI_BIT_EN , 0x00 },
1240 { STB0899_MATSTRM , 0x00 },
1241 { STB0899_MATSTRL , 0x00 },
1242 { STB0899_UPLSTRM , 0x00 },
1243 { STB0899_UPLSTRL , 0x00 },
1244 { STB0899_DFLSTRM , 0x00 },
1245 { STB0899_DFLSTRL , 0x00 },
1246 { STB0899_SYNCSTR , 0x00 },
1247 { STB0899_SYNCDSTRM , 0x00 },
1248 { STB0899_SYNCDSTRL , 0x00 },
1249 { STB0899_CFGPDELSTATUS1 , 0x10 },
1250 { STB0899_CFGPDELSTATUS2 , 0x00 },
1251 { STB0899_BBFERRORM , 0x00 },
1252 { STB0899_BBFERRORL , 0x00 },
1253 { STB0899_UPKTERRORM , 0x00 },
1254 { STB0899_UPKTERRORL , 0x00 },
1255 { 0xffff , 0xff },
1258 static struct stb0899_config tt3200_config = {
1259 .init_dev = tt3200_stb0899_s1_init_1,
1260 .init_s2_demod = stb0899_s2_init_2,
1261 .init_s1_demod = tt3200_stb0899_s1_init_3,
1262 .init_s2_fec = stb0899_s2_init_4,
1263 .init_tst = stb0899_s1_init_5,
1265 .postproc = NULL,
1267 .demod_address = 0x68,
1269 .xtal_freq = 27000000,
1270 .inversion = IQ_SWAP_ON, /* 1 */
1272 .lo_clk = 76500000,
1273 .hi_clk = 99000000,
1275 .esno_ave = STB0899_DVBS2_ESNO_AVE,
1276 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
1277 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
1278 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
1279 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
1280 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1281 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1282 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
1283 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1285 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
1286 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1287 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
1288 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
1290 .tuner_get_frequency = stb6100_get_frequency,
1291 .tuner_set_frequency = stb6100_set_frequency,
1292 .tuner_set_bandwidth = stb6100_set_bandwidth,
1293 .tuner_get_bandwidth = stb6100_get_bandwidth,
1294 .tuner_set_rfsiggain = NULL
1297 static struct stb6100_config tt3200_stb6100_config = {
1298 .tuner_address = 0x60,
1299 .refclock = 27000000,
1302 static void frontend_init(struct budget_ci *budget_ci)
1304 switch (budget_ci->budget.dev->pci->subsystem_device) {
1305 case 0x100c: // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
1306 budget_ci->budget.dvb_frontend =
1307 dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
1308 if (budget_ci->budget.dvb_frontend) {
1309 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
1310 budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1311 break;
1313 break;
1315 case 0x100f: // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
1316 budget_ci->budget.dvb_frontend =
1317 dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
1318 if (budget_ci->budget.dvb_frontend) {
1319 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
1320 break;
1322 break;
1324 case 0x1010: // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
1325 budget_ci->tuner_pll_address = 0x61;
1326 budget_ci->budget.dvb_frontend =
1327 dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1328 if (budget_ci->budget.dvb_frontend) {
1329 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1330 break;
1332 break;
1334 case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
1335 budget_ci->tuner_pll_address = 0x63;
1336 budget_ci->budget.dvb_frontend =
1337 dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1338 if (budget_ci->budget.dvb_frontend) {
1339 budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1340 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1341 break;
1343 break;
1345 case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
1346 budget_ci->tuner_pll_address = 0x60;
1347 budget_ci->budget.dvb_frontend =
1348 dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
1349 if (budget_ci->budget.dvb_frontend) {
1350 budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1351 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1352 break;
1354 break;
1356 case 0x1017: // TT S-1500 PCI
1357 budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
1358 if (budget_ci->budget.dvb_frontend) {
1359 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
1360 budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1362 budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
1363 if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
1364 printk("%s: No LNBP21 found!\n", __func__);
1365 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1366 budget_ci->budget.dvb_frontend = NULL;
1369 break;
1371 case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
1372 budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
1373 if (budget_ci->budget.dvb_frontend) {
1374 if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
1375 printk(KERN_ERR "%s: No tda827x found!\n", __func__);
1376 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1377 budget_ci->budget.dvb_frontend = NULL;
1380 break;
1382 case 0x1019: // TT S2-3200 PCI
1384 * NOTE! on some STB0899 versions, the internal PLL takes a longer time
1385 * to settle, aka LOCK. On the older revisions of the chip, we don't see
1386 * this, as a result on the newer chips the entire clock tree, will not
1387 * be stable after a freshly POWER 'ed up situation.
1388 * In this case, we should RESET the STB0899 (Active LOW) and wait for
1389 * PLL stabilization.
1391 * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is
1392 * connected to the SAA7146 GPIO, GPIO2, Pin 142
1394 /* Reset Demodulator */
1395 saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
1396 /* Wait for everything to die */
1397 msleep(50);
1398 /* Pull it up out of Reset state */
1399 saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
1400 /* Wait for PLL to stabilize */
1401 msleep(250);
1403 * PLL state should be stable now. Ideally, we should check
1404 * for PLL LOCK status. But well, never mind!
1406 budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
1407 if (budget_ci->budget.dvb_frontend) {
1408 if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
1409 if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1410 printk("%s: No LNBP21 found!\n", __func__);
1411 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1412 budget_ci->budget.dvb_frontend = NULL;
1414 } else {
1415 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1416 budget_ci->budget.dvb_frontend = NULL;
1419 break;
1423 if (budget_ci->budget.dvb_frontend == NULL) {
1424 printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1425 budget_ci->budget.dev->pci->vendor,
1426 budget_ci->budget.dev->pci->device,
1427 budget_ci->budget.dev->pci->subsystem_vendor,
1428 budget_ci->budget.dev->pci->subsystem_device);
1429 } else {
1430 if (dvb_register_frontend
1431 (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
1432 printk("budget-ci: Frontend registration failed!\n");
1433 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1434 budget_ci->budget.dvb_frontend = NULL;
1439 static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1441 struct budget_ci *budget_ci;
1442 int err;
1444 budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
1445 if (!budget_ci) {
1446 err = -ENOMEM;
1447 goto out1;
1450 dprintk(2, "budget_ci: %p\n", budget_ci);
1452 dev->ext_priv = budget_ci;
1454 err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
1455 adapter_nr);
1456 if (err)
1457 goto out2;
1459 err = msp430_ir_init(budget_ci);
1460 if (err)
1461 goto out3;
1463 ciintf_init(budget_ci);
1465 budget_ci->budget.dvb_adapter.priv = budget_ci;
1466 frontend_init(budget_ci);
1468 ttpci_budget_init_hooks(&budget_ci->budget);
1470 return 0;
1472 out3:
1473 ttpci_budget_deinit(&budget_ci->budget);
1474 out2:
1475 kfree(budget_ci);
1476 out1:
1477 return err;
1480 static int budget_ci_detach(struct saa7146_dev *dev)
1482 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
1483 struct saa7146_dev *saa = budget_ci->budget.dev;
1484 int err;
1486 if (budget_ci->budget.ci_present)
1487 ciintf_deinit(budget_ci);
1488 msp430_ir_deinit(budget_ci);
1489 if (budget_ci->budget.dvb_frontend) {
1490 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
1491 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1493 err = ttpci_budget_deinit(&budget_ci->budget);
1495 // disable frontend and CI interface
1496 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1498 kfree(budget_ci);
1500 return err;
1503 static struct saa7146_extension budget_extension;
1505 MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
1506 MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1507 MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
1508 MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1509 MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1510 MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1511 MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1513 static struct pci_device_id pci_tbl[] = {
1514 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
1515 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
1516 MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
1517 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
1518 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
1519 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1520 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1521 MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1523 .vendor = 0,
1527 MODULE_DEVICE_TABLE(pci, pci_tbl);
1529 static struct saa7146_extension budget_extension = {
1530 .name = "budget_ci dvb",
1531 .flags = SAA7146_USE_I2C_IRQ,
1533 .module = THIS_MODULE,
1534 .pci_tbl = &pci_tbl[0],
1535 .attach = budget_ci_attach,
1536 .detach = budget_ci_detach,
1538 .irq_mask = MASK_03 | MASK_06 | MASK_10,
1539 .irq_func = budget_ci_irq,
1542 static int __init budget_ci_init(void)
1544 return saa7146_register_extension(&budget_extension);
1547 static void __exit budget_ci_exit(void)
1549 saa7146_unregister_extension(&budget_extension);
1552 module_init(budget_ci_init);
1553 module_exit(budget_ci_exit);
1555 MODULE_LICENSE("GPL");
1556 MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1557 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1558 "budget PCI DVB cards w/ CI-module produced by "
1559 "Siemens, Technotrend, Hauppauge");