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

source code of linux/drivers/media/pci/ttpci/budget-ci.c