1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <linux/module.h>
30#include <linux/errno.h>
31#include <linux/slab.h>
32#include <linux/interrupt.h>
33#include <linux/spinlock.h>
34#include <media/rc-core.h>
35
36#include "budget.h"
37
38#include <media/dvb_ca_en50221.h>
39#include "stv0299.h"
40#include "stv0297.h"
41#include "tda1004x.h"
42#include "stb0899_drv.h"
43#include "stb0899_reg.h"
44#include "stb0899_cfg.h"
45#include "stb6100.h"
46#include "stb6100_cfg.h"
47#include "lnbp21.h"
48#include "bsbe1.h"
49#include "bsru6.h"
50#include "tda1002x.h"
51#include "tda827x.h"
52#include "bsbe1-d01a.h"
53
54#define MODULE_NAME "budget_ci"
55
56
57
58
59
60
61
62
63#define DEBIADDR_IR 0x4000
64#define DEBIADDR_CICONTROL 0x0000
65#define DEBIADDR_CIVERSION 0x4000
66#define DEBIADDR_IO 0x1000
67#define DEBIADDR_ATTR 0x3000
68
69#define CICONTROL_RESET 0x01
70#define CICONTROL_ENABLETS 0x02
71#define CICONTROL_CAMDETECT 0x08
72
73#define DEBICICTL 0x00420000
74#define DEBICICAM 0x02420000
75
76#define SLOTSTATUS_NONE 1
77#define SLOTSTATUS_PRESENT 2
78#define SLOTSTATUS_RESET 4
79#define SLOTSTATUS_READY 8
80#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
81
82
83#define IR_DEVICE_ANY 255
84
85static int rc5_device = -1;
86module_param(rc5_device, int, 0644);
87MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
88
89static int ir_debug;
90module_param(ir_debug, int, 0644);
91MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
92
93DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
94
95struct budget_ci_ir {
96 struct rc_dev *dev;
97 struct tasklet_struct msp430_irq_tasklet;
98 char name[72];
99 char phys[32];
100 int rc5_device;
101 u32 ir_key;
102 bool have_command;
103 bool full_rc5;
104};
105
106struct budget_ci {
107 struct budget budget;
108 struct tasklet_struct ciintf_irq_tasklet;
109 int slot_status;
110 int ci_irq;
111 struct dvb_ca_en50221 ca;
112 struct budget_ci_ir ir;
113 u8 tuner_pll_address;
114};
115
116static void msp430_ir_interrupt(unsigned long data)
117{
118 struct budget_ci *budget_ci = (struct budget_ci *) data;
119 struct rc_dev *dev = budget_ci->ir.dev;
120 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 if (ir_debug)
139 printk("budget_ci: received byte 0x%02x\n", command);
140
141
142 command = command & 0x7f;
143
144
145 if (command & 0x40) {
146 budget_ci->ir.have_command = true;
147 budget_ci->ir.ir_key = command & 0x3f;
148 return;
149 }
150
151
152 if (!budget_ci->ir.have_command)
153 return;
154 budget_ci->ir.have_command = false;
155
156 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
157 budget_ci->ir.rc5_device != (command & 0x1f))
158 return;
159
160 if (budget_ci->ir.full_rc5) {
161 rc_keydown(dev, RC_PROTO_RC5,
162 RC_SCANCODE_RC5(budget_ci->ir.rc5_device, budget_ci->ir.ir_key),
163 !!(command & 0x20));
164 return;
165 }
166
167
168 rc_keydown(dev, RC_PROTO_UNKNOWN, budget_ci->ir.ir_key,
169 !!(command & 0x20));
170}
171
172static int msp430_ir_init(struct budget_ci *budget_ci)
173{
174 struct saa7146_dev *saa = budget_ci->budget.dev;
175 struct rc_dev *dev;
176 int error;
177
178 dev = rc_allocate_device(RC_DRIVER_SCANCODE);
179 if (!dev) {
180 printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
181 return -ENOMEM;
182 }
183
184 snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
185 "Budget-CI dvb ir receiver %s", saa->name);
186 snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
187 "pci-%s/ir0", pci_name(saa->pci));
188
189 dev->driver_name = MODULE_NAME;
190 dev->device_name = budget_ci->ir.name;
191 dev->input_phys = budget_ci->ir.phys;
192 dev->input_id.bustype = BUS_PCI;
193 dev->input_id.version = 1;
194 if (saa->pci->subsystem_vendor) {
195 dev->input_id.vendor = saa->pci->subsystem_vendor;
196 dev->input_id.product = saa->pci->subsystem_device;
197 } else {
198 dev->input_id.vendor = saa->pci->vendor;
199 dev->input_id.product = saa->pci->device;
200 }
201 dev->dev.parent = &saa->pci->dev;
202
203 if (rc5_device < 0)
204 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
205 else
206 budget_ci->ir.rc5_device = rc5_device;
207
208
209 switch (budget_ci->budget.dev->pci->subsystem_device) {
210 case 0x100c:
211 case 0x100f:
212 case 0x1011:
213 case 0x1012:
214
215 dev->map_name = RC_MAP_HAUPPAUGE;
216 budget_ci->ir.full_rc5 = true;
217
218 if (rc5_device < 0)
219 budget_ci->ir.rc5_device = 0x1f;
220 break;
221 case 0x1010:
222 case 0x1017:
223 case 0x1019:
224 case 0x101a:
225 case 0x101b:
226
227 dev->map_name = RC_MAP_TT_1500;
228 break;
229 default:
230
231 dev->map_name = RC_MAP_BUDGET_CI_OLD;
232 break;
233 }
234 if (!budget_ci->ir.full_rc5)
235 dev->scancode_mask = 0xff;
236
237 error = rc_register_device(dev);
238 if (error) {
239 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
240 rc_free_device(dev);
241 return error;
242 }
243
244 budget_ci->ir.dev = dev;
245
246 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
247 (unsigned long) budget_ci);
248
249 SAA7146_IER_ENABLE(saa, MASK_06);
250 saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
251
252 return 0;
253}
254
255static void msp430_ir_deinit(struct budget_ci *budget_ci)
256{
257 struct saa7146_dev *saa = budget_ci->budget.dev;
258
259 SAA7146_IER_DISABLE(saa, MASK_06);
260 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
261 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
262
263 rc_unregister_device(budget_ci->ir.dev);
264}
265
266static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
267{
268 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
269
270 if (slot != 0)
271 return -EINVAL;
272
273 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
274 DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
275}
276
277static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
278{
279 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
280
281 if (slot != 0)
282 return -EINVAL;
283
284 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
285 DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
286}
287
288static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
289{
290 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
291
292 if (slot != 0)
293 return -EINVAL;
294
295 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
296 DEBIADDR_IO | (address & 3), 1, 1, 0);
297}
298
299static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
300{
301 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
302
303 if (slot != 0)
304 return -EINVAL;
305
306 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
307 DEBIADDR_IO | (address & 3), 1, value, 1, 0);
308}
309
310static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
311{
312 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
313 struct saa7146_dev *saa = budget_ci->budget.dev;
314
315 if (slot != 0)
316 return -EINVAL;
317
318 if (budget_ci->ci_irq) {
319
320 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
321 }
322 budget_ci->slot_status = SLOTSTATUS_RESET;
323 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
324 msleep(1);
325 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
326 CICONTROL_RESET, 1, 0);
327
328 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
329 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
330 return 0;
331}
332
333static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
334{
335 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
336 struct saa7146_dev *saa = budget_ci->budget.dev;
337
338 if (slot != 0)
339 return -EINVAL;
340
341 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
342 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
343 return 0;
344}
345
346static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
347{
348 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
349 struct saa7146_dev *saa = budget_ci->budget.dev;
350 int tmp;
351
352 if (slot != 0)
353 return -EINVAL;
354
355 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
356
357 tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
358 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
359 tmp | CICONTROL_ENABLETS, 1, 0);
360
361 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
362 return 0;
363}
364
365static void ciintf_interrupt(unsigned long data)
366{
367 struct budget_ci *budget_ci = (struct budget_ci *) data;
368 struct saa7146_dev *saa = budget_ci->budget.dev;
369 unsigned int flags;
370
371
372 if (!budget_ci->budget.ci_present)
373 return;
374
375
376 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
377 if (flags & CICONTROL_CAMDETECT) {
378
379
380 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
381
382 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
383
384 budget_ci->slot_status = SLOTSTATUS_PRESENT;
385 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
386 DVB_CA_EN50221_CAMCHANGE_INSERTED);
387
388 } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
389
390 budget_ci->slot_status = SLOTSTATUS_READY;
391 dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
392
393 } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
394
395 dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
396 }
397 } else {
398
399
400
401
402 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
403
404
405 if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
406
407 budget_ci->slot_status = SLOTSTATUS_NONE;
408 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
409 DVB_CA_EN50221_CAMCHANGE_REMOVED);
410 }
411 }
412}
413
414static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
415{
416 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
417 unsigned int flags;
418
419
420 if (!budget_ci->budget.ci_present)
421 return -EINVAL;
422
423
424 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
425 if (flags & CICONTROL_CAMDETECT) {
426
427 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
428 budget_ci->slot_status = SLOTSTATUS_PRESENT;
429 }
430
431
432 if (budget_ci->slot_status & SLOTSTATUS_RESET) {
433 if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
434 budget_ci->slot_status = SLOTSTATUS_READY;
435 }
436 }
437 } else {
438 budget_ci->slot_status = SLOTSTATUS_NONE;
439 }
440
441 if (budget_ci->slot_status != SLOTSTATUS_NONE) {
442 if (budget_ci->slot_status & SLOTSTATUS_READY) {
443 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
444 }
445 return DVB_CA_EN50221_POLL_CAM_PRESENT;
446 }
447
448 return 0;
449}
450
451static int ciintf_init(struct budget_ci *budget_ci)
452{
453 struct saa7146_dev *saa = budget_ci->budget.dev;
454 int flags;
455 int result;
456 int ci_version;
457 int ca_flags;
458
459 memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
460
461
462 saa7146_write(saa, MC1, MASK_27 | MASK_11);
463
464
465 ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
466 if ((ci_version & 0xa0) != 0xa0) {
467 result = -ENODEV;
468 goto error;
469 }
470
471
472 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
473 budget_ci->slot_status = SLOTSTATUS_NONE;
474 if (flags & CICONTROL_CAMDETECT)
475 budget_ci->slot_status = SLOTSTATUS_PRESENT;
476
477
478 if (ci_version == 0xa2) {
479 ca_flags = 0;
480 budget_ci->ci_irq = 0;
481 } else {
482 ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
483 DVB_CA_EN50221_FLAG_IRQ_FR |
484 DVB_CA_EN50221_FLAG_IRQ_DA;
485 budget_ci->ci_irq = 1;
486 }
487
488
489 budget_ci->ca.owner = THIS_MODULE;
490 budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
491 budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
492 budget_ci->ca.read_cam_control = ciintf_read_cam_control;
493 budget_ci->ca.write_cam_control = ciintf_write_cam_control;
494 budget_ci->ca.slot_reset = ciintf_slot_reset;
495 budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
496 budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
497 budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
498 budget_ci->ca.data = budget_ci;
499 if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
500 &budget_ci->ca,
501 ca_flags, 1)) != 0) {
502 printk("budget_ci: CI interface detected, but initialisation failed.\n");
503 goto error;
504 }
505
506
507 if (budget_ci->ci_irq) {
508 tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
509 if (budget_ci->slot_status != SLOTSTATUS_NONE) {
510 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
511 } else {
512 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
513 }
514 SAA7146_IER_ENABLE(saa, MASK_03);
515 }
516
517
518 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
519 CICONTROL_RESET, 1, 0);
520
521
522 printk("budget_ci: CI interface initialised\n");
523 budget_ci->budget.ci_present = 1;
524
525
526 if (budget_ci->ci_irq) {
527 flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
528 if (budget_ci->slot_status != SLOTSTATUS_NONE)
529 flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
530 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
531 }
532
533 return 0;
534
535error:
536 saa7146_write(saa, MC1, MASK_27);
537 return result;
538}
539
540static void ciintf_deinit(struct budget_ci *budget_ci)
541{
542 struct saa7146_dev *saa = budget_ci->budget.dev;
543
544
545 if (budget_ci->ci_irq) {
546 SAA7146_IER_DISABLE(saa, MASK_03);
547 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
548 tasklet_kill(&budget_ci->ciintf_irq_tasklet);
549 }
550
551
552 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
553 msleep(1);
554 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
555 CICONTROL_RESET, 1, 0);
556
557
558 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
559
560
561 dvb_ca_en50221_release(&budget_ci->ca);
562
563
564 saa7146_write(saa, MC1, MASK_27);
565}
566
567static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
568{
569 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
570
571 dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
572
573 if (*isr & MASK_06)
574 tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
575
576 if (*isr & MASK_10)
577 ttpci_budget_irq10_handler(dev, isr);
578
579 if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
580 tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
581}
582
583static u8 philips_su1278_tt_inittab[] = {
584 0x01, 0x0f,
585 0x02, 0x30,
586 0x03, 0x00,
587 0x04, 0x5b,
588 0x05, 0x85,
589 0x06, 0x02,
590 0x07, 0x00,
591 0x08, 0x02,
592 0x09, 0x00,
593 0x0C, 0x01,
594 0x0D, 0x81,
595 0x0E, 0x44,
596 0x0f, 0x14,
597 0x10, 0x3c,
598 0x11, 0x84,
599 0x12, 0xda,
600 0x13, 0x97,
601 0x14, 0x95,
602 0x15, 0xc9,
603 0x16, 0x19,
604 0x17, 0x8c,
605 0x18, 0x59,
606 0x19, 0xf8,
607 0x1a, 0xfe,
608 0x1c, 0x7f,
609 0x1d, 0x00,
610 0x1e, 0x00,
611 0x1f, 0x50,
612 0x20, 0x00,
613 0x21, 0x00,
614 0x22, 0x00,
615 0x23, 0x00,
616 0x28, 0x00,
617 0x29, 0x28,
618 0x2a, 0x14,
619 0x2b, 0x0f,
620 0x2c, 0x09,
621 0x2d, 0x09,
622 0x31, 0x1f,
623 0x32, 0x19,
624 0x33, 0xfc,
625 0x34, 0x93,
626 0xff, 0xff
627};
628
629static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
630{
631 stv0299_writereg(fe, 0x0e, 0x44);
632 if (srate >= 10000000) {
633 stv0299_writereg(fe, 0x13, 0x97);
634 stv0299_writereg(fe, 0x14, 0x95);
635 stv0299_writereg(fe, 0x15, 0xc9);
636 stv0299_writereg(fe, 0x17, 0x8c);
637 stv0299_writereg(fe, 0x1a, 0xfe);
638 stv0299_writereg(fe, 0x1c, 0x7f);
639 stv0299_writereg(fe, 0x2d, 0x09);
640 } else {
641 stv0299_writereg(fe, 0x13, 0x99);
642 stv0299_writereg(fe, 0x14, 0x8d);
643 stv0299_writereg(fe, 0x15, 0xce);
644 stv0299_writereg(fe, 0x17, 0x43);
645 stv0299_writereg(fe, 0x1a, 0x1d);
646 stv0299_writereg(fe, 0x1c, 0x12);
647 stv0299_writereg(fe, 0x2d, 0x05);
648 }
649 stv0299_writereg(fe, 0x0e, 0x23);
650 stv0299_writereg(fe, 0x0f, 0x94);
651 stv0299_writereg(fe, 0x10, 0x39);
652 stv0299_writereg(fe, 0x15, 0xc9);
653
654 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
655 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
656 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
657
658 return 0;
659}
660
661static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe)
662{
663 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
664 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
665 u32 div;
666 u8 buf[4];
667 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
668
669 if ((p->frequency < 950000) || (p->frequency > 2150000))
670 return -EINVAL;
671
672 div = (p->frequency + (500 - 1)) / 500;
673 buf[0] = (div >> 8) & 0x7f;
674 buf[1] = div & 0xff;
675 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
676 buf[3] = 0x20;
677
678 if (p->symbol_rate < 4000000)
679 buf[3] |= 1;
680
681 if (p->frequency < 1250000)
682 buf[3] |= 0;
683 else if (p->frequency < 1550000)
684 buf[3] |= 0x40;
685 else if (p->frequency < 2050000)
686 buf[3] |= 0x80;
687 else if (p->frequency < 2150000)
688 buf[3] |= 0xC0;
689
690 if (fe->ops.i2c_gate_ctrl)
691 fe->ops.i2c_gate_ctrl(fe, 1);
692 if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
693 return -EIO;
694 return 0;
695}
696
697static const struct stv0299_config philips_su1278_tt_config = {
698
699 .demod_address = 0x68,
700 .inittab = philips_su1278_tt_inittab,
701 .mclk = 64000000UL,
702 .invert = 0,
703 .skip_reinit = 1,
704 .lock_output = STV0299_LOCKOUTPUT_1,
705 .volt13_op0_op1 = STV0299_VOLT13_OP1,
706 .min_delay_ms = 50,
707 .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
708};
709
710
711
712static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
713{
714 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
715 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
716 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
717 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
718 sizeof(td1316_init) };
719
720
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 return -EIO;
725 msleep(1);
726
727
728 tuner_msg.addr = 0x65;
729 tuner_msg.buf = disable_mc44BC374c;
730 tuner_msg.len = sizeof(disable_mc44BC374c);
731 if (fe->ops.i2c_gate_ctrl)
732 fe->ops.i2c_gate_ctrl(fe, 1);
733 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
734 if (fe->ops.i2c_gate_ctrl)
735 fe->ops.i2c_gate_ctrl(fe, 1);
736 i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
737 }
738
739 return 0;
740}
741
742static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
743{
744 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
745 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
746 u8 tuner_buf[4];
747 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
748 int tuner_frequency = 0;
749 u8 band, cp, filter;
750
751
752 tuner_frequency = p->frequency + 36130000;
753 if (tuner_frequency < 87000000)
754 return -EINVAL;
755 else if (tuner_frequency < 130000000)
756 cp = 3;
757 else if (tuner_frequency < 160000000)
758 cp = 5;
759 else if (tuner_frequency < 200000000)
760 cp = 6;
761 else if (tuner_frequency < 290000000)
762 cp = 3;
763 else if (tuner_frequency < 420000000)
764 cp = 5;
765 else if (tuner_frequency < 480000000)
766 cp = 6;
767 else if (tuner_frequency < 620000000)
768 cp = 3;
769 else if (tuner_frequency < 830000000)
770 cp = 5;
771 else if (tuner_frequency < 895000000)
772 cp = 7;
773 else
774 return -EINVAL;
775
776
777 if (p->frequency < 49000000)
778 return -EINVAL;
779 else if (p->frequency < 159000000)
780 band = 1;
781 else if (p->frequency < 444000000)
782 band = 2;
783 else if (p->frequency < 861000000)
784 band = 4;
785 else
786 return -EINVAL;
787
788
789 switch (p->bandwidth_hz) {
790 case 6000000:
791 tda1004x_writereg(fe, 0x0C, 0x14);
792 filter = 0;
793 break;
794
795 case 7000000:
796 tda1004x_writereg(fe, 0x0C, 0x80);
797 filter = 0;
798 break;
799
800 case 8000000:
801 tda1004x_writereg(fe, 0x0C, 0x14);
802 filter = 1;
803 break;
804
805 default:
806 return -EINVAL;
807 }
808
809
810
811 tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000;
812
813
814 tuner_buf[0] = tuner_frequency >> 8;
815 tuner_buf[1] = tuner_frequency & 0xff;
816 tuner_buf[2] = 0xca;
817 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
818
819 if (fe->ops.i2c_gate_ctrl)
820 fe->ops.i2c_gate_ctrl(fe, 1);
821 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
822 return -EIO;
823
824 msleep(1);
825 return 0;
826}
827
828static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
829 const struct firmware **fw, char *name)
830{
831 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
832
833 return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
834}
835
836static struct tda1004x_config philips_tdm1316l_config = {
837
838 .demod_address = 0x8,
839 .invert = 0,
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,
845};
846
847static struct tda1004x_config philips_tdm1316l_config_invert = {
848
849 .demod_address = 0x8,
850 .invert = 1,
851 .invert_oclk = 0,
852 .xtal_freq = TDA10046_XTAL_4M,
853 .agc_config = TDA10046_AGC_DEFAULT,
854 .if_freq = TDA10046_FREQ_3617,
855 .request_firmware = philips_tdm1316l_request_firmware,
856};
857
858static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
859{
860 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
861 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
862 u8 tuner_buf[5];
863 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
864 .flags = 0,
865 .buf = tuner_buf,
866 .len = sizeof(tuner_buf) };
867 int tuner_frequency = 0;
868 u8 band, cp, filter;
869
870
871 tuner_frequency = p->frequency + 36125000;
872 if (tuner_frequency < 87000000)
873 return -EINVAL;
874 else if (tuner_frequency < 130000000) {
875 cp = 3;
876 band = 1;
877 } else if (tuner_frequency < 160000000) {
878 cp = 5;
879 band = 1;
880 } else if (tuner_frequency < 200000000) {
881 cp = 6;
882 band = 1;
883 } else if (tuner_frequency < 290000000) {
884 cp = 3;
885 band = 2;
886 } else if (tuner_frequency < 420000000) {
887 cp = 5;
888 band = 2;
889 } else if (tuner_frequency < 480000000) {
890 cp = 6;
891 band = 2;
892 } else if (tuner_frequency < 620000000) {
893 cp = 3;
894 band = 4;
895 } else if (tuner_frequency < 830000000) {
896 cp = 5;
897 band = 4;
898 } else if (tuner_frequency < 895000000) {
899 cp = 7;
900 band = 4;
901 } else
902 return -EINVAL;
903
904
905 filter = 1;
906
907
908 tuner_frequency = (p->frequency + 36125000 + (62500/2)) / 62500;
909
910
911 tuner_buf[0] = tuner_frequency >> 8;
912 tuner_buf[1] = tuner_frequency & 0xff;
913 tuner_buf[2] = 0xc8;
914 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
915 tuner_buf[4] = 0x80;
916
917 if (fe->ops.i2c_gate_ctrl)
918 fe->ops.i2c_gate_ctrl(fe, 1);
919 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
920 return -EIO;
921
922 msleep(50);
923
924 if (fe->ops.i2c_gate_ctrl)
925 fe->ops.i2c_gate_ctrl(fe, 1);
926 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
927 return -EIO;
928
929 msleep(1);
930
931 return 0;
932}
933
934static u8 dvbc_philips_tdm1316l_inittab[] = {
935 0x80, 0x01,
936 0x80, 0x00,
937 0x81, 0x01,
938 0x81, 0x00,
939 0x00, 0x09,
940 0x01, 0x69,
941 0x03, 0x00,
942 0x04, 0x00,
943 0x07, 0x00,
944 0x08, 0x00,
945 0x20, 0x00,
946 0x21, 0x40,
947 0x22, 0x00,
948 0x23, 0x00,
949 0x24, 0x40,
950 0x25, 0x88,
951 0x30, 0xff,
952 0x31, 0x00,
953 0x32, 0xff,
954 0x33, 0x00,
955 0x34, 0x50,
956 0x35, 0x7f,
957 0x36, 0x00,
958 0x37, 0x20,
959 0x38, 0x00,
960 0x40, 0x1c,
961 0x41, 0xff,
962 0x42, 0x29,
963 0x43, 0x20,
964 0x44, 0xff,
965 0x45, 0x00,
966 0x46, 0x00,
967 0x49, 0x04,
968 0x4a, 0x00,
969 0x4b, 0x7b,
970 0x52, 0x30,
971 0x55, 0xae,
972 0x56, 0x47,
973 0x57, 0xe1,
974 0x58, 0x3a,
975 0x5a, 0x1e,
976 0x5b, 0x34,
977 0x60, 0x00,
978 0x63, 0x00,
979 0x64, 0x00,
980 0x65, 0x00,
981 0x66, 0x00,
982 0x67, 0x00,
983 0x68, 0x00,
984 0x69, 0x00,
985 0x6a, 0x02,
986 0x6b, 0x00,
987 0x70, 0xff,
988 0x71, 0x00,
989 0x72, 0x00,
990 0x73, 0x00,
991 0x74, 0x0c,
992 0x80, 0x00,
993 0x81, 0x00,
994 0x82, 0x00,
995 0x83, 0x00,
996 0x84, 0x04,
997 0x85, 0x80,
998 0x86, 0x24,
999 0x87, 0x78,
1000 0x88, 0x10,
1001 0x89, 0x00,
1002 0x90, 0x01,
1003 0x91, 0x01,
1004 0xa0, 0x04,
1005 0xa1, 0x00,
1006 0xa2, 0x00,
1007 0xb0, 0x91,
1008 0xb1, 0x0b,
1009 0xc0, 0x53,
1010 0xc1, 0x70,
1011 0xc2, 0x12,
1012 0xd0, 0x00,
1013 0xd1, 0x00,
1014 0xd2, 0x00,
1015 0xd3, 0x00,
1016 0xd4, 0x00,
1017 0xd5, 0x00,
1018 0xde, 0x00,
1019 0xdf, 0x00,
1020 0x61, 0x38,
1021 0x62, 0x0a,
1022 0x53, 0x13,
1023 0x59, 0x08,
1024 0xff, 0xff,
1025};
1026
1027static struct stv0297_config dvbc_philips_tdm1316l_config = {
1028 .demod_address = 0x1c,
1029 .inittab = dvbc_philips_tdm1316l_inittab,
1030 .invert = 0,
1031 .stop_during_read = 1,
1032};
1033
1034static struct tda10023_config tda10023_config = {
1035 .demod_address = 0xc,
1036 .invert = 0,
1037 .xtal = 16000000,
1038 .pll_m = 11,
1039 .pll_p = 3,
1040 .pll_n = 1,
1041 .deltaf = 0xa511,
1042};
1043
1044static struct tda827x_config tda827x_config = {
1045 .config = 0,
1046};
1047
1048
1049static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
1050
1051 { STB0899_DEV_ID , 0x81 },
1052 { STB0899_DISCNTRL1 , 0x32 },
1053 { STB0899_DISCNTRL2 , 0x80 },
1054 { STB0899_DISRX_ST0 , 0x04 },
1055 { STB0899_DISRX_ST1 , 0x00 },
1056 { STB0899_DISPARITY , 0x00 },
1057 { STB0899_DISSTATUS , 0x20 },
1058 { STB0899_DISF22 , 0x8c },
1059 { STB0899_DISF22RX , 0x9a },
1060 { STB0899_SYSREG , 0x0b },
1061 { STB0899_ACRPRESC , 0x11 },
1062 { STB0899_ACRDIV1 , 0x0a },
1063 { STB0899_ACRDIV2 , 0x05 },
1064 { STB0899_DACR1 , 0x00 },
1065 { STB0899_DACR2 , 0x00 },
1066 { STB0899_OUTCFG , 0x00 },
1067 { STB0899_MODECFG , 0x00 },
1068 { STB0899_IRQSTATUS_3 , 0x30 },
1069 { STB0899_IRQSTATUS_2 , 0x00 },
1070 { STB0899_IRQSTATUS_1 , 0x00 },
1071 { STB0899_IRQSTATUS_0 , 0x00 },
1072 { STB0899_IRQMSK_3 , 0xf3 },
1073 { STB0899_IRQMSK_2 , 0xfc },
1074 { STB0899_IRQMSK_1 , 0xff },
1075 { STB0899_IRQMSK_0 , 0xff },
1076 { STB0899_IRQCFG , 0x00 },
1077 { STB0899_I2CCFG , 0x88 },
1078 { STB0899_I2CRPT , 0x48 },
1079 { STB0899_IOPVALUE5 , 0x00 },
1080 { STB0899_IOPVALUE4 , 0x20 },
1081 { STB0899_IOPVALUE3 , 0xc9 },
1082 { STB0899_IOPVALUE2 , 0x90 },
1083 { STB0899_IOPVALUE1 , 0x40 },
1084 { STB0899_IOPVALUE0 , 0x00 },
1085 { STB0899_GPIO00CFG , 0x82 },
1086 { STB0899_GPIO01CFG , 0x82 },
1087 { STB0899_GPIO02CFG , 0x82 },
1088 { STB0899_GPIO03CFG , 0x82 },
1089 { STB0899_GPIO04CFG , 0x82 },
1090 { STB0899_GPIO05CFG , 0x82 },
1091 { STB0899_GPIO06CFG , 0x82 },
1092 { STB0899_GPIO07CFG , 0x82 },
1093 { STB0899_GPIO08CFG , 0x82 },
1094 { STB0899_GPIO09CFG , 0x82 },
1095 { STB0899_GPIO10CFG , 0x82 },
1096 { STB0899_GPIO11CFG , 0x82 },
1097 { STB0899_GPIO12CFG , 0x82 },
1098 { STB0899_GPIO13CFG , 0x82 },
1099 { STB0899_GPIO14CFG , 0x82 },
1100 { STB0899_GPIO15CFG , 0x82 },
1101 { STB0899_GPIO16CFG , 0x82 },
1102 { STB0899_GPIO17CFG , 0x82 },
1103 { STB0899_GPIO18CFG , 0x82 },
1104 { STB0899_GPIO19CFG , 0x82 },
1105 { STB0899_GPIO20CFG , 0x82 },
1106 { STB0899_SDATCFG , 0xb8 },
1107 { STB0899_SCLTCFG , 0xba },
1108 { STB0899_AGCRFCFG , 0x1c },
1109 { STB0899_GPIO22 , 0x82 },
1110 { STB0899_GPIO21 , 0x91 },
1111 { STB0899_DIRCLKCFG , 0x82 },
1112 { STB0899_CLKOUT27CFG , 0x7e },
1113 { STB0899_STDBYCFG , 0x82 },
1114 { STB0899_CS0CFG , 0x82 },
1115 { STB0899_CS1CFG , 0x82 },
1116 { STB0899_DISEQCOCFG , 0x20 },
1117 { STB0899_GPIO32CFG , 0x82 },
1118 { STB0899_GPIO33CFG , 0x82 },
1119 { STB0899_GPIO34CFG , 0x82 },
1120 { STB0899_GPIO35CFG , 0x82 },
1121 { STB0899_GPIO36CFG , 0x82 },
1122 { STB0899_GPIO37CFG , 0x82 },
1123 { STB0899_GPIO38CFG , 0x82 },
1124 { STB0899_GPIO39CFG , 0x82 },
1125 { STB0899_NCOARSE , 0x15 },
1126 { STB0899_SYNTCTRL , 0x02 },
1127 { STB0899_FILTCTRL , 0x00 },
1128 { STB0899_SYSCTRL , 0x00 },
1129 { STB0899_STOPCLK1 , 0x20 },
1130 { STB0899_STOPCLK2 , 0x00 },
1131 { STB0899_INTBUFSTATUS , 0x00 },
1132 { STB0899_INTBUFCTRL , 0x0a },
1133 { 0xffff , 0xff },
1134};
1135
1136static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
1137 { STB0899_DEMOD , 0x00 },
1138 { STB0899_RCOMPC , 0xc9 },
1139 { STB0899_AGC1CN , 0x41 },
1140 { STB0899_AGC1REF , 0x10 },
1141 { STB0899_RTC , 0x7a },
1142 { STB0899_TMGCFG , 0x4e },
1143 { STB0899_AGC2REF , 0x34 },
1144 { STB0899_TLSR , 0x84 },
1145 { STB0899_CFD , 0xc7 },
1146 { STB0899_ACLC , 0x87 },
1147 { STB0899_BCLC , 0x94 },
1148 { STB0899_EQON , 0x41 },
1149 { STB0899_LDT , 0xdd },
1150 { STB0899_LDT2 , 0xc9 },
1151 { STB0899_EQUALREF , 0xb4 },
1152 { STB0899_TMGRAMP , 0x10 },
1153 { STB0899_TMGTHD , 0x30 },
1154 { STB0899_IDCCOMP , 0xfb },
1155 { STB0899_QDCCOMP , 0x03 },
1156 { STB0899_POWERI , 0x3b },
1157 { STB0899_POWERQ , 0x3d },
1158 { STB0899_RCOMP , 0x81 },
1159 { STB0899_AGCIQIN , 0x80 },
1160 { STB0899_AGC2I1 , 0x04 },
1161 { STB0899_AGC2I2 , 0xf5 },
1162 { STB0899_TLIR , 0x25 },
1163 { STB0899_RTF , 0x80 },
1164 { STB0899_DSTATUS , 0x00 },
1165 { STB0899_LDI , 0xca },
1166 { STB0899_CFRM , 0xf1 },
1167 { STB0899_CFRL , 0xf3 },
1168 { STB0899_NIRM , 0x2a },
1169 { STB0899_NIRL , 0x05 },
1170 { STB0899_ISYMB , 0x17 },
1171 { STB0899_QSYMB , 0xfa },
1172 { STB0899_SFRH , 0x2f },
1173 { STB0899_SFRM , 0x68 },
1174 { STB0899_SFRL , 0x40 },
1175 { STB0899_SFRUPH , 0x2f },
1176 { STB0899_SFRUPM , 0x68 },
1177 { STB0899_SFRUPL , 0x40 },
1178 { STB0899_EQUAI1 , 0xfd },
1179 { STB0899_EQUAQ1 , 0x04 },
1180 { STB0899_EQUAI2 , 0x0f },
1181 { STB0899_EQUAQ2 , 0xff },
1182 { STB0899_EQUAI3 , 0xdf },
1183 { STB0899_EQUAQ3 , 0xfa },
1184 { STB0899_EQUAI4 , 0x37 },
1185 { STB0899_EQUAQ4 , 0x0d },
1186 { STB0899_EQUAI5 , 0xbd },
1187 { STB0899_EQUAQ5 , 0xf7 },
1188 { STB0899_DSTATUS2 , 0x00 },
1189 { STB0899_VSTATUS , 0x00 },
1190 { STB0899_VERROR , 0xff },
1191 { STB0899_IQSWAP , 0x2a },
1192 { STB0899_ECNT1M , 0x00 },
1193 { STB0899_ECNT1L , 0x00 },
1194 { STB0899_ECNT2M , 0x00 },
1195 { STB0899_ECNT2L , 0x00 },
1196 { STB0899_ECNT3M , 0x00 },
1197 { STB0899_ECNT3L , 0x00 },
1198 { STB0899_FECAUTO1 , 0x06 },
1199 { STB0899_FECM , 0x01 },
1200 { STB0899_VTH12 , 0xf0 },
1201 { STB0899_VTH23 , 0xa0 },
1202 { STB0899_VTH34 , 0x78 },
1203 { STB0899_VTH56 , 0x4e },
1204 { STB0899_VTH67 , 0x48 },
1205 { STB0899_VTH78 , 0x38 },
1206 { STB0899_PRVIT , 0xff },
1207 { STB0899_VITSYNC , 0x19 },
1208 { STB0899_RSULC , 0xb1 },
1209 { STB0899_TSULC , 0x42 },
1210 { STB0899_RSLLC , 0x40 },
1211 { STB0899_TSLPL , 0x12 },
1212 { STB0899_TSCFGH , 0x0c },
1213 { STB0899_TSCFGM , 0x00 },
1214 { STB0899_TSCFGL , 0x0c },
1215 { STB0899_TSOUT , 0x4d },
1216 { STB0899_RSSYNCDEL , 0x00 },
1217 { STB0899_TSINHDELH , 0x02 },
1218 { STB0899_TSINHDELM , 0x00 },
1219 { STB0899_TSINHDELL , 0x00 },
1220 { STB0899_TSLLSTKM , 0x00 },
1221 { STB0899_TSLLSTKL , 0x00 },
1222 { STB0899_TSULSTKM , 0x00 },
1223 { STB0899_TSULSTKL , 0xab },
1224 { STB0899_PCKLENUL , 0x00 },
1225 { STB0899_PCKLENLL , 0xcc },
1226 { STB0899_RSPCKLEN , 0xcc },
1227 { STB0899_TSSTATUS , 0x80 },
1228 { STB0899_ERRCTRL1 , 0xb6 },
1229 { STB0899_ERRCTRL2 , 0x96 },
1230 { STB0899_ERRCTRL3 , 0x89 },
1231 { STB0899_DMONMSK1 , 0x27 },
1232 { STB0899_DMONMSK0 , 0x03 },
1233 { STB0899_DEMAPVIT , 0x5c },
1234 { STB0899_PLPARM , 0x1f },
1235 { STB0899_PDELCTRL , 0x48 },
1236 { STB0899_PDELCTRL2 , 0x00 },
1237 { STB0899_BBHCTRL1 , 0x00 },
1238 { STB0899_BBHCTRL2 , 0x00 },
1239 { STB0899_HYSTTHRESH , 0x77 },
1240 { STB0899_MATCSTM , 0x00 },
1241 { STB0899_MATCSTL , 0x00 },
1242 { STB0899_UPLCSTM , 0x00 },
1243 { STB0899_UPLCSTL , 0x00 },
1244 { STB0899_DFLCSTM , 0x00 },
1245 { STB0899_DFLCSTL , 0x00 },
1246 { STB0899_SYNCCST , 0x00 },
1247 { STB0899_SYNCDCSTM , 0x00 },
1248 { STB0899_SYNCDCSTL , 0x00 },
1249 { STB0899_ISI_ENTRY , 0x00 },
1250 { STB0899_ISI_BIT_EN , 0x00 },
1251 { STB0899_MATSTRM , 0x00 },
1252 { STB0899_MATSTRL , 0x00 },
1253 { STB0899_UPLSTRM , 0x00 },
1254 { STB0899_UPLSTRL , 0x00 },
1255 { STB0899_DFLSTRM , 0x00 },
1256 { STB0899_DFLSTRL , 0x00 },
1257 { STB0899_SYNCSTR , 0x00 },
1258 { STB0899_SYNCDSTRM , 0x00 },
1259 { STB0899_SYNCDSTRL , 0x00 },
1260 { STB0899_CFGPDELSTATUS1 , 0x10 },
1261 { STB0899_CFGPDELSTATUS2 , 0x00 },
1262 { STB0899_BBFERRORM , 0x00 },
1263 { STB0899_BBFERRORL , 0x00 },
1264 { STB0899_UPKTERRORM , 0x00 },
1265 { STB0899_UPKTERRORL , 0x00 },
1266 { 0xffff , 0xff },
1267};
1268
1269static struct stb0899_config tt3200_config = {
1270 .init_dev = tt3200_stb0899_s1_init_1,
1271 .init_s2_demod = stb0899_s2_init_2,
1272 .init_s1_demod = tt3200_stb0899_s1_init_3,
1273 .init_s2_fec = stb0899_s2_init_4,
1274 .init_tst = stb0899_s1_init_5,
1275
1276 .postproc = NULL,
1277
1278 .demod_address = 0x68,
1279
1280 .xtal_freq = 27000000,
1281 .inversion = IQ_SWAP_ON,
1282
1283 .lo_clk = 76500000,
1284 .hi_clk = 99000000,
1285
1286 .esno_ave = STB0899_DVBS2_ESNO_AVE,
1287 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
1288 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
1289 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
1290 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
1291 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1292 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1293 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
1294 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1295
1296 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
1297 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1298 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
1299 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
1300
1301 .tuner_get_frequency = stb6100_get_frequency,
1302 .tuner_set_frequency = stb6100_set_frequency,
1303 .tuner_set_bandwidth = stb6100_set_bandwidth,
1304 .tuner_get_bandwidth = stb6100_get_bandwidth,
1305 .tuner_set_rfsiggain = NULL
1306};
1307
1308static struct stb6100_config tt3200_stb6100_config = {
1309 .tuner_address = 0x60,
1310 .refclock = 27000000,
1311};
1312
1313static void frontend_init(struct budget_ci *budget_ci)
1314{
1315 switch (budget_ci->budget.dev->pci->subsystem_device) {
1316 case 0x100c:
1317 budget_ci->budget.dvb_frontend =
1318 dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
1319 if (budget_ci->budget.dvb_frontend) {
1320 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
1321 budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1322 break;
1323 }
1324 break;
1325
1326 case 0x100f:
1327 budget_ci->budget.dvb_frontend =
1328 dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
1329 if (budget_ci->budget.dvb_frontend) {
1330 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
1331 break;
1332 }
1333 break;
1334
1335 case 0x1010:
1336 budget_ci->tuner_pll_address = 0x61;
1337 budget_ci->budget.dvb_frontend =
1338 dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1339 if (budget_ci->budget.dvb_frontend) {
1340 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1341 break;
1342 }
1343 break;
1344
1345 case 0x1011:
1346 budget_ci->tuner_pll_address = 0x63;
1347 budget_ci->budget.dvb_frontend =
1348 dvb_attach(tda10045_attach, &philips_tdm1316l_config, &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;
1353 }
1354 break;
1355
1356 case 0x1012:
1357 budget_ci->tuner_pll_address = 0x60;
1358 budget_ci->budget.dvb_frontend =
1359 dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
1360 if (budget_ci->budget.dvb_frontend) {
1361 budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1362 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1363 break;
1364 }
1365 break;
1366
1367 case 0x1017:
1368 budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
1369 if (budget_ci->budget.dvb_frontend) {
1370 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
1371 budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1372
1373 budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
1374 if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
1375 printk("%s: No LNBP21 found!\n", __func__);
1376 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1377 budget_ci->budget.dvb_frontend = NULL;
1378 }
1379 }
1380 break;
1381
1382 case 0x101a:
1383 budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
1384 if (budget_ci->budget.dvb_frontend) {
1385 if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
1386 printk(KERN_ERR "%s: No tda827x found!\n", __func__);
1387 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1388 budget_ci->budget.dvb_frontend = NULL;
1389 }
1390 }
1391 break;
1392
1393 case 0x101b:
1394 budget_ci->budget.dvb_frontend = dvb_attach(stv0288_attach, &stv0288_bsbe1_d01a_config, &budget_ci->budget.i2c_adap);
1395 if (budget_ci->budget.dvb_frontend) {
1396 if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) {
1397 if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1398 printk(KERN_ERR "%s: No LNBP21 found!\n", __func__);
1399 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1400 budget_ci->budget.dvb_frontend = NULL;
1401 }
1402 } else {
1403 printk(KERN_ERR "%s: No STB6000 found!\n", __func__);
1404 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1405 budget_ci->budget.dvb_frontend = NULL;
1406 }
1407 }
1408 break;
1409
1410 case 0x1019:
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423 saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
1424
1425 msleep(50);
1426
1427 saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
1428
1429 msleep(250);
1430
1431
1432
1433
1434 budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
1435 if (budget_ci->budget.dvb_frontend) {
1436 if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
1437 if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1438 printk("%s: No LNBP21 found!\n", __func__);
1439 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1440 budget_ci->budget.dvb_frontend = NULL;
1441 }
1442 } else {
1443 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1444 budget_ci->budget.dvb_frontend = NULL;
1445 }
1446 }
1447 break;
1448
1449 }
1450
1451 if (budget_ci->budget.dvb_frontend == NULL) {
1452 printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1453 budget_ci->budget.dev->pci->vendor,
1454 budget_ci->budget.dev->pci->device,
1455 budget_ci->budget.dev->pci->subsystem_vendor,
1456 budget_ci->budget.dev->pci->subsystem_device);
1457 } else {
1458 if (dvb_register_frontend
1459 (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
1460 printk("budget-ci: Frontend registration failed!\n");
1461 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1462 budget_ci->budget.dvb_frontend = NULL;
1463 }
1464 }
1465}
1466
1467static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1468{
1469 struct budget_ci *budget_ci;
1470 int err;
1471
1472 budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
1473 if (!budget_ci) {
1474 err = -ENOMEM;
1475 goto out1;
1476 }
1477
1478 dprintk(2, "budget_ci: %p\n", budget_ci);
1479
1480 dev->ext_priv = budget_ci;
1481
1482 err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
1483 adapter_nr);
1484 if (err)
1485 goto out2;
1486
1487 err = msp430_ir_init(budget_ci);
1488 if (err)
1489 goto out3;
1490
1491 ciintf_init(budget_ci);
1492
1493 budget_ci->budget.dvb_adapter.priv = budget_ci;
1494 frontend_init(budget_ci);
1495
1496 ttpci_budget_init_hooks(&budget_ci->budget);
1497
1498 return 0;
1499
1500out3:
1501 ttpci_budget_deinit(&budget_ci->budget);
1502out2:
1503 kfree(budget_ci);
1504out1:
1505 return err;
1506}
1507
1508static int budget_ci_detach(struct saa7146_dev *dev)
1509{
1510 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
1511 struct saa7146_dev *saa = budget_ci->budget.dev;
1512 int err;
1513
1514 if (budget_ci->budget.ci_present)
1515 ciintf_deinit(budget_ci);
1516 msp430_ir_deinit(budget_ci);
1517 if (budget_ci->budget.dvb_frontend) {
1518 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
1519 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1520 }
1521 err = ttpci_budget_deinit(&budget_ci->budget);
1522
1523
1524 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1525
1526 kfree(budget_ci);
1527
1528 return err;
1529}
1530
1531static struct saa7146_extension budget_extension;
1532
1533MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
1534MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1535MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
1536MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1537MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1538MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1539MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1540MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT);
1541
1542static const struct pci_device_id pci_tbl[] = {
1543 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
1544 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
1545 MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
1546 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
1547 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
1548 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1549 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1550 MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1551 MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b),
1552 {
1553 .vendor = 0,
1554 }
1555};
1556
1557MODULE_DEVICE_TABLE(pci, pci_tbl);
1558
1559static struct saa7146_extension budget_extension = {
1560 .name = "budget_ci dvb",
1561 .flags = SAA7146_USE_I2C_IRQ,
1562
1563 .module = THIS_MODULE,
1564 .pci_tbl = &pci_tbl[0],
1565 .attach = budget_ci_attach,
1566 .detach = budget_ci_detach,
1567
1568 .irq_mask = MASK_03 | MASK_06 | MASK_10,
1569 .irq_func = budget_ci_irq,
1570};
1571
1572static int __init budget_ci_init(void)
1573{
1574 return saa7146_register_extension(&budget_extension);
1575}
1576
1577static void __exit budget_ci_exit(void)
1578{
1579 saa7146_unregister_extension(&budget_extension);
1580}
1581
1582module_init(budget_ci_init);
1583module_exit(budget_ci_exit);
1584
1585MODULE_LICENSE("GPL");
1586MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1587MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards w/ CI-module produced by Siemens, Technotrend, Hauppauge");
1588