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