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