V4L/DVB (3532): Moved duplicated code of ALPS BSRU6 tuner to a standalone file.
[deliverable/linux.git] / drivers / media / dvb / ttpci / budget-ci.c
CommitLineData
1da177e4
LT
1/*
2 * budget-ci.c: driver for the SAA7146 based Budget DVB cards
3 *
4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
5 *
6 * msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
7 * partially based on the Siemens DVB driver by Ralph+Marcus Metzler
8 *
9 * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
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/dvb/
30 */
31
32#include "budget.h"
33
34#include <linux/module.h>
35#include <linux/errno.h>
36#include <linux/slab.h>
37#include <linux/interrupt.h>
38#include <linux/input.h>
39#include <linux/spinlock.h>
40
41#include "dvb_ca_en50221.h"
42#include "stv0299.h"
dc27a169 43#include "stv0297.h"
1da177e4 44#include "tda1004x.h"
8cc2e377
PA
45#include "lnbp21.h"
46#include "bsbe1.h"
265366e8 47#include "bsru6.h"
1da177e4
LT
48
49#define DEBIADDR_IR 0x1234
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
68struct budget_ci {
69 struct budget budget;
b7df3910 70 struct input_dev *input_dev;
1da177e4
LT
71 struct tasklet_struct msp430_irq_tasklet;
72 struct tasklet_struct ciintf_irq_tasklet;
73 int slot_status;
74 struct dvb_ca_en50221 ca;
75 char ir_dev_name[50];
dd2bbb17 76 u8 tuner_pll_address; /* used for philips_tdm1316l configs */
1da177e4
LT
77};
78
79/* from reading the following remotes:
80 Zenith Universal 7 / TV Mode 807 / VCR Mode 837
81 Hauppauge (from NOVA-CI-s box product)
82 i've taken a "middle of the road" approach and note the differences
83*/
84static u16 key_map[64] = {
85 /* 0x0X */
86 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8,
87 KEY_9,
88 KEY_ENTER,
89 KEY_RED,
90 KEY_POWER, /* RADIO on Hauppauge */
91 KEY_MUTE,
92 0,
93 KEY_A, /* TV on Hauppauge */
94 /* 0x1X */
95 KEY_VOLUMEUP, KEY_VOLUMEDOWN,
96 0, 0,
97 KEY_B,
98 0, 0, 0, 0, 0, 0, 0,
99 KEY_UP, KEY_DOWN,
100 KEY_OPTION, /* RESERVED on Hauppauge */
101 KEY_BREAK,
102 /* 0x2X */
103 KEY_CHANNELUP, KEY_CHANNELDOWN,
104 KEY_PREVIOUS, /* Prev. Ch on Zenith, SOURCE on Hauppauge */
105 0, KEY_RESTART, KEY_OK,
106 KEY_CYCLEWINDOWS, /* MINIMIZE on Hauppauge */
107 0,
108 KEY_ENTER, /* VCR mode on Zenith */
109 KEY_PAUSE,
110 0,
111 KEY_RIGHT, KEY_LEFT,
112 0,
113 KEY_MENU, /* FULL SCREEN on Hauppauge */
114 0,
115 /* 0x3X */
116 KEY_SLOW,
117 KEY_PREVIOUS, /* VCR mode on Zenith */
118 KEY_REWIND,
119 0,
120 KEY_FASTFORWARD,
121 KEY_PLAY, KEY_STOP,
122 KEY_RECORD,
123 KEY_TUNER, /* TV/VCR on Zenith */
124 0,
125 KEY_C,
126 0,
127 KEY_EXIT,
128 KEY_POWER2,
129 KEY_TUNER, /* VCR mode on Zenith */
130 0,
131};
132
133static void msp430_ir_debounce(unsigned long data)
134{
135 struct input_dev *dev = (struct input_dev *) data;
136
137 if (dev->rep[0] == 0 || dev->rep[0] == ~0) {
138 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
139 return;
140 }
141
142 dev->rep[0] = 0;
143 dev->timer.expires = jiffies + HZ * 350 / 1000;
144 add_timer(&dev->timer);
145 input_event(dev, EV_KEY, key_map[dev->repeat_key], 2); /* REPEAT */
146}
147
148static void msp430_ir_interrupt(unsigned long data)
149{
150 struct budget_ci *budget_ci = (struct budget_ci *) data;
b7df3910 151 struct input_dev *dev = budget_ci->input_dev;
1da177e4
LT
152 unsigned int code =
153 ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
154
155 if (code & 0x40) {
156 code &= 0x3f;
157
158 if (timer_pending(&dev->timer)) {
159 if (code == dev->repeat_key) {
160 ++dev->rep[0];
161 return;
162 }
163 del_timer(&dev->timer);
164 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
165 }
166
167 if (!key_map[code]) {
168 printk("DVB (%s): no key for %02x!\n", __FUNCTION__, code);
169 return;
170 }
171
172 /* initialize debounce and repeat */
173 dev->repeat_key = code;
174 /* Zenith remote _always_ sends 2 sequences */
175 dev->rep[0] = ~0;
176 /* 350 milliseconds */
177 dev->timer.expires = jiffies + HZ * 350 / 1000;
178 /* MAKE */
179 input_event(dev, EV_KEY, key_map[code], !0);
180 add_timer(&dev->timer);
181 }
182}
183
184static int msp430_ir_init(struct budget_ci *budget_ci)
185{
186 struct saa7146_dev *saa = budget_ci->budget.dev;
b7df3910 187 struct input_dev *input_dev;
1da177e4
LT
188 int i;
189
b7df3910
DT
190 budget_ci->input_dev = input_dev = input_allocate_device();
191 if (!input_dev)
192 return -ENOMEM;
1da177e4
LT
193
194 sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name);
1da177e4 195
b7df3910 196 input_dev->name = budget_ci->ir_dev_name;
1da177e4 197
b7df3910
DT
198 set_bit(EV_KEY, input_dev->evbit);
199 for (i = 0; i < ARRAY_SIZE(key_map); i++)
1da177e4 200 if (key_map[i])
b7df3910 201 set_bit(key_map[i], input_dev->keybit);
1da177e4 202
b7df3910 203 input_register_device(budget_ci->input_dev);
1da177e4 204
b7df3910 205 input_dev->timer.function = msp430_ir_debounce;
1da177e4
LT
206
207 saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
1da177e4
LT
208 saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
209
210 return 0;
211}
212
213static void msp430_ir_deinit(struct budget_ci *budget_ci)
214{
215 struct saa7146_dev *saa = budget_ci->budget.dev;
b7df3910 216 struct input_dev *dev = budget_ci->input_dev;
1da177e4
LT
217
218 saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
219 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
220
221 if (del_timer(&dev->timer))
222 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
223
224 input_unregister_device(dev);
225}
226
227static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
228{
229 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
230
231 if (slot != 0)
232 return -EINVAL;
233
234 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
235 DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
236}
237
238static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
239{
240 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
241
242 if (slot != 0)
243 return -EINVAL;
244
245 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
246 DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
247}
248
249static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
250{
251 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
252
253 if (slot != 0)
254 return -EINVAL;
255
256 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
257 DEBIADDR_IO | (address & 3), 1, 1, 0);
258}
259
260static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
261{
262 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
263
264 if (slot != 0)
265 return -EINVAL;
266
267 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
268 DEBIADDR_IO | (address & 3), 1, value, 1, 0);
269}
270
271static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
272{
273 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
274 struct saa7146_dev *saa = budget_ci->budget.dev;
275
276 if (slot != 0)
277 return -EINVAL;
278
279 // trigger on RISING edge during reset so we know when READY is re-asserted
280 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
281 budget_ci->slot_status = SLOTSTATUS_RESET;
282 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
283 msleep(1);
284 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
285 CICONTROL_RESET, 1, 0);
286
287 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
288 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
289 return 0;
290}
291
292static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
293{
294 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
295 struct saa7146_dev *saa = budget_ci->budget.dev;
296
297 if (slot != 0)
298 return -EINVAL;
299
300 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
301 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
302 return 0;
303}
304
305static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
306{
307 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
308 struct saa7146_dev *saa = budget_ci->budget.dev;
309 int tmp;
310
311 if (slot != 0)
312 return -EINVAL;
313
314 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
315
316 tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
317 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
318 tmp | CICONTROL_ENABLETS, 1, 0);
319
320 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
321 return 0;
322}
323
324static void ciintf_interrupt(unsigned long data)
325{
326 struct budget_ci *budget_ci = (struct budget_ci *) data;
327 struct saa7146_dev *saa = budget_ci->budget.dev;
328 unsigned int flags;
329
330 // ensure we don't get spurious IRQs during initialisation
331 if (!budget_ci->budget.ci_present)
332 return;
333
334 // read the CAM status
335 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
336 if (flags & CICONTROL_CAMDETECT) {
337
338 // GPIO should be set to trigger on falling edge if a CAM is present
339 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
340
341 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
342 // CAM insertion IRQ
343 budget_ci->slot_status = SLOTSTATUS_PRESENT;
344 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
345 DVB_CA_EN50221_CAMCHANGE_INSERTED);
346
347 } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
348 // CAM ready (reset completed)
349 budget_ci->slot_status = SLOTSTATUS_READY;
350 dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
351
352 } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
353 // FR/DA IRQ
354 dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
355 }
356 } else {
357
358 // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
359 // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
360 // the CAM might not actually be ready yet.
361 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
362
363 // generate a CAM removal IRQ if we haven't already
364 if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
365 // CAM removal IRQ
366 budget_ci->slot_status = SLOTSTATUS_NONE;
367 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
368 DVB_CA_EN50221_CAMCHANGE_REMOVED);
369 }
370 }
371}
372
373static int ciintf_init(struct budget_ci *budget_ci)
374{
375 struct saa7146_dev *saa = budget_ci->budget.dev;
376 int flags;
377 int result;
378
379 memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
380
381 // enable DEBI pins
382 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
383
384 // test if it is there
385 if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) {
386 result = -ENODEV;
387 goto error;
388 }
389 // determine whether a CAM is present or not
390 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
391 budget_ci->slot_status = SLOTSTATUS_NONE;
392 if (flags & CICONTROL_CAMDETECT)
393 budget_ci->slot_status = SLOTSTATUS_PRESENT;
394
395 // register CI interface
396 budget_ci->ca.owner = THIS_MODULE;
397 budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
398 budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
399 budget_ci->ca.read_cam_control = ciintf_read_cam_control;
400 budget_ci->ca.write_cam_control = ciintf_write_cam_control;
401 budget_ci->ca.slot_reset = ciintf_slot_reset;
402 budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
403 budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
404 budget_ci->ca.data = budget_ci;
fdc53a6d 405 if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
1da177e4
LT
406 &budget_ci->ca,
407 DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
408 DVB_CA_EN50221_FLAG_IRQ_FR |
409 DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) {
410 printk("budget_ci: CI interface detected, but initialisation failed.\n");
411 goto error;
412 }
413 // Setup CI slot IRQ
414 tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
415 if (budget_ci->slot_status != SLOTSTATUS_NONE) {
416 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
417 } else {
418 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
419 }
420 saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
421 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
422 CICONTROL_RESET, 1, 0);
423
424 // success!
425 printk("budget_ci: CI interface initialised\n");
426 budget_ci->budget.ci_present = 1;
427
428 // forge a fake CI IRQ so the CAM state is setup correctly
429 flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
430 if (budget_ci->slot_status != SLOTSTATUS_NONE)
431 flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
432 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
433
434 return 0;
435
436error:
437 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
438 return result;
439}
440
441static void ciintf_deinit(struct budget_ci *budget_ci)
442{
443 struct saa7146_dev *saa = budget_ci->budget.dev;
444
445 // disable CI interrupts
446 saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
447 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
448 tasklet_kill(&budget_ci->ciintf_irq_tasklet);
449 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
450 msleep(1);
451 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
452 CICONTROL_RESET, 1, 0);
453
454 // disable TS data stream to CI interface
455 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
456
457 // release the CA device
458 dvb_ca_en50221_release(&budget_ci->ca);
459
460 // disable DEBI pins
461 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
462}
463
464static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
465{
466 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
467
468 dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
469
470 if (*isr & MASK_06)
471 tasklet_schedule(&budget_ci->msp430_irq_tasklet);
472
473 if (*isr & MASK_10)
474 ttpci_budget_irq10_handler(dev, isr);
475
476 if ((*isr & MASK_03) && (budget_ci->budget.ci_present))
477 tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
478}
479
1da177e4
LT
480static u8 philips_su1278_tt_inittab[] = {
481 0x01, 0x0f,
482 0x02, 0x30,
483 0x03, 0x00,
484 0x04, 0x5b,
485 0x05, 0x85,
486 0x06, 0x02,
487 0x07, 0x00,
488 0x08, 0x02,
489 0x09, 0x00,
490 0x0C, 0x01,
491 0x0D, 0x81,
492 0x0E, 0x44,
493 0x0f, 0x14,
494 0x10, 0x3c,
495 0x11, 0x84,
496 0x12, 0xda,
497 0x13, 0x97,
498 0x14, 0x95,
499 0x15, 0xc9,
500 0x16, 0x19,
501 0x17, 0x8c,
502 0x18, 0x59,
503 0x19, 0xf8,
504 0x1a, 0xfe,
505 0x1c, 0x7f,
506 0x1d, 0x00,
507 0x1e, 0x00,
508 0x1f, 0x50,
509 0x20, 0x00,
510 0x21, 0x00,
511 0x22, 0x00,
512 0x23, 0x00,
513 0x28, 0x00,
514 0x29, 0x28,
515 0x2a, 0x14,
516 0x2b, 0x0f,
517 0x2c, 0x09,
518 0x2d, 0x09,
519 0x31, 0x1f,
520 0x32, 0x19,
521 0x33, 0xfc,
522 0x34, 0x93,
523 0xff, 0xff
524};
525
526static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
527{
528 stv0299_writereg(fe, 0x0e, 0x44);
529 if (srate >= 10000000) {
530 stv0299_writereg(fe, 0x13, 0x97);
531 stv0299_writereg(fe, 0x14, 0x95);
532 stv0299_writereg(fe, 0x15, 0xc9);
533 stv0299_writereg(fe, 0x17, 0x8c);
534 stv0299_writereg(fe, 0x1a, 0xfe);
535 stv0299_writereg(fe, 0x1c, 0x7f);
536 stv0299_writereg(fe, 0x2d, 0x09);
537 } else {
538 stv0299_writereg(fe, 0x13, 0x99);
539 stv0299_writereg(fe, 0x14, 0x8d);
540 stv0299_writereg(fe, 0x15, 0xce);
541 stv0299_writereg(fe, 0x17, 0x43);
542 stv0299_writereg(fe, 0x1a, 0x1d);
543 stv0299_writereg(fe, 0x1c, 0x12);
544 stv0299_writereg(fe, 0x2d, 0x05);
545 }
546 stv0299_writereg(fe, 0x0e, 0x23);
547 stv0299_writereg(fe, 0x0f, 0x94);
548 stv0299_writereg(fe, 0x10, 0x39);
549 stv0299_writereg(fe, 0x15, 0xc9);
550
551 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
552 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
553 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
554
555 return 0;
556}
557
558static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
cfbfce15 559 struct i2c_adapter *i2c,
1da177e4
LT
560 struct dvb_frontend_parameters *params)
561{
1da177e4
LT
562 u32 div;
563 u8 buf[4];
564 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
565
566 if ((params->frequency < 950000) || (params->frequency > 2150000))
567 return -EINVAL;
568
569 div = (params->frequency + (500 - 1)) / 500; // round correctly
570 buf[0] = (div >> 8) & 0x7f;
571 buf[1] = div & 0xff;
572 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
573 buf[3] = 0x20;
574
575 if (params->u.qpsk.symbol_rate < 4000000)
576 buf[3] |= 1;
577
578 if (params->frequency < 1250000)
579 buf[3] |= 0;
580 else if (params->frequency < 1550000)
581 buf[3] |= 0x40;
582 else if (params->frequency < 2050000)
583 buf[3] |= 0x80;
584 else if (params->frequency < 2150000)
585 buf[3] |= 0xC0;
586
cfbfce15 587 if (i2c_transfer(i2c, &msg, 1) != 1)
1da177e4
LT
588 return -EIO;
589 return 0;
590}
591
592static struct stv0299_config philips_su1278_tt_config = {
593
594 .demod_address = 0x68,
595 .inittab = philips_su1278_tt_inittab,
596 .mclk = 64000000UL,
597 .invert = 0,
1da177e4
LT
598 .skip_reinit = 1,
599 .lock_output = STV0229_LOCKOUTPUT_1,
600 .volt13_op0_op1 = STV0299_VOLT13_OP1,
601 .min_delay_ms = 50,
602 .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
603 .pll_set = philips_su1278_tt_pll_set,
604};
605
606
607
608static int philips_tdm1316l_pll_init(struct dvb_frontend *fe)
609{
610 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
611 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
612 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
dd2bbb17 613 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
1da177e4
LT
614 sizeof(td1316_init) };
615
616 // setup PLL configuration
617 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
618 return -EIO;
619 msleep(1);
620
621 // disable the mc44BC374c (do not check for errors)
622 tuner_msg.addr = 0x65;
623 tuner_msg.buf = disable_mc44BC374c;
624 tuner_msg.len = sizeof(disable_mc44BC374c);
625 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
626 i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
627 }
628
629 return 0;
630}
631
632static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
633{
634 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
635 u8 tuner_buf[4];
dd2bbb17 636 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
1da177e4
LT
637 int tuner_frequency = 0;
638 u8 band, cp, filter;
639
640 // determine charge pump
641 tuner_frequency = params->frequency + 36130000;
642 if (tuner_frequency < 87000000)
643 return -EINVAL;
644 else if (tuner_frequency < 130000000)
645 cp = 3;
646 else if (tuner_frequency < 160000000)
647 cp = 5;
648 else if (tuner_frequency < 200000000)
649 cp = 6;
650 else if (tuner_frequency < 290000000)
651 cp = 3;
652 else if (tuner_frequency < 420000000)
653 cp = 5;
654 else if (tuner_frequency < 480000000)
655 cp = 6;
656 else if (tuner_frequency < 620000000)
657 cp = 3;
658 else if (tuner_frequency < 830000000)
659 cp = 5;
660 else if (tuner_frequency < 895000000)
661 cp = 7;
662 else
663 return -EINVAL;
664
665 // determine band
666 if (params->frequency < 49000000)
667 return -EINVAL;
668 else if (params->frequency < 159000000)
669 band = 1;
670 else if (params->frequency < 444000000)
671 band = 2;
672 else if (params->frequency < 861000000)
673 band = 4;
674 else
675 return -EINVAL;
676
677 // setup PLL filter and TDA9889
678 switch (params->u.ofdm.bandwidth) {
679 case BANDWIDTH_6_MHZ:
680 tda1004x_write_byte(fe, 0x0C, 0x14);
681 filter = 0;
682 break;
683
684 case BANDWIDTH_7_MHZ:
685 tda1004x_write_byte(fe, 0x0C, 0x80);
686 filter = 0;
687 break;
688
689 case BANDWIDTH_8_MHZ:
690 tda1004x_write_byte(fe, 0x0C, 0x14);
691 filter = 1;
692 break;
693
694 default:
695 return -EINVAL;
696 }
697
698 // calculate divisor
699 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
700 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
701
702 // setup tuner buffer
703 tuner_buf[0] = tuner_frequency >> 8;
704 tuner_buf[1] = tuner_frequency & 0xff;
705 tuner_buf[2] = 0xca;
706 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
707
708 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
709 return -EIO;
710
711 msleep(1);
712 return 0;
713}
714
715static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
716 const struct firmware **fw, char *name)
717{
718 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
719
720 return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
721}
722
723static struct tda1004x_config philips_tdm1316l_config = {
724
725 .demod_address = 0x8,
726 .invert = 0,
727 .invert_oclk = 0,
ecb60deb
HH
728 .xtal_freq = TDA10046_XTAL_4M,
729 .agc_config = TDA10046_AGC_DEFAULT,
730 .if_freq = TDA10046_FREQ_3617,
1da177e4
LT
731 .pll_init = philips_tdm1316l_pll_init,
732 .pll_set = philips_tdm1316l_pll_set,
ecb60deb 733 .pll_sleep = NULL,
1da177e4
LT
734 .request_firmware = philips_tdm1316l_request_firmware,
735};
736
dc27a169
AQ
737static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
738{
739 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
740 u8 tuner_buf[5];
741 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
742 .flags = 0,
743 .buf = tuner_buf,
744 .len = sizeof(tuner_buf) };
745 int tuner_frequency = 0;
746 u8 band, cp, filter;
747
748 // determine charge pump
749 tuner_frequency = params->frequency + 36125000;
750 if (tuner_frequency < 87000000)
751 return -EINVAL;
752 else if (tuner_frequency < 130000000) {
753 cp = 3;
754 band = 1;
755 } else if (tuner_frequency < 160000000) {
756 cp = 5;
757 band = 1;
758 } else if (tuner_frequency < 200000000) {
759 cp = 6;
760 band = 1;
761 } else if (tuner_frequency < 290000000) {
762 cp = 3;
763 band = 2;
764 } else if (tuner_frequency < 420000000) {
765 cp = 5;
766 band = 2;
767 } else if (tuner_frequency < 480000000) {
768 cp = 6;
769 band = 2;
770 } else if (tuner_frequency < 620000000) {
771 cp = 3;
772 band = 4;
773 } else if (tuner_frequency < 830000000) {
774 cp = 5;
775 band = 4;
776 } else if (tuner_frequency < 895000000) {
777 cp = 7;
778 band = 4;
779 } else
780 return -EINVAL;
781
782 // assume PLL filter should always be 8MHz for the moment.
783 filter = 1;
784
785 // calculate divisor
786 tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500;
787
788 // setup tuner buffer
789 tuner_buf[0] = tuner_frequency >> 8;
790 tuner_buf[1] = tuner_frequency & 0xff;
791 tuner_buf[2] = 0xc8;
792 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
793 tuner_buf[4] = 0x80;
794
795 stv0297_enable_plli2c(fe);
796 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
797 return -EIO;
798
799 msleep(50);
800
801 stv0297_enable_plli2c(fe);
802 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
803 return -EIO;
804
805 msleep(1);
806
807 return 0;
808}
809
810static u8 dvbc_philips_tdm1316l_inittab[] = {
811 0x80, 0x01,
812 0x80, 0x00,
813 0x81, 0x01,
814 0x81, 0x00,
815 0x00, 0x09,
816 0x01, 0x69,
817 0x03, 0x00,
818 0x04, 0x00,
819 0x07, 0x00,
820 0x08, 0x00,
821 0x20, 0x00,
822 0x21, 0x40,
823 0x22, 0x00,
824 0x23, 0x00,
825 0x24, 0x40,
826 0x25, 0x88,
827 0x30, 0xff,
828 0x31, 0x00,
829 0x32, 0xff,
830 0x33, 0x00,
831 0x34, 0x50,
832 0x35, 0x7f,
833 0x36, 0x00,
834 0x37, 0x20,
835 0x38, 0x00,
836 0x40, 0x1c,
837 0x41, 0xff,
838 0x42, 0x29,
839 0x43, 0x20,
840 0x44, 0xff,
841 0x45, 0x00,
842 0x46, 0x00,
843 0x49, 0x04,
844 0x4a, 0x00,
845 0x4b, 0x7b,
846 0x52, 0x30,
847 0x55, 0xae,
848 0x56, 0x47,
849 0x57, 0xe1,
850 0x58, 0x3a,
851 0x5a, 0x1e,
852 0x5b, 0x34,
853 0x60, 0x00,
854 0x63, 0x00,
855 0x64, 0x00,
856 0x65, 0x00,
857 0x66, 0x00,
858 0x67, 0x00,
859 0x68, 0x00,
860 0x69, 0x00,
861 0x6a, 0x02,
862 0x6b, 0x00,
863 0x70, 0xff,
864 0x71, 0x00,
865 0x72, 0x00,
866 0x73, 0x00,
867 0x74, 0x0c,
868 0x80, 0x00,
869 0x81, 0x00,
870 0x82, 0x00,
871 0x83, 0x00,
872 0x84, 0x04,
873 0x85, 0x80,
874 0x86, 0x24,
875 0x87, 0x78,
876 0x88, 0x10,
877 0x89, 0x00,
878 0x90, 0x01,
879 0x91, 0x01,
880 0xa0, 0x04,
881 0xa1, 0x00,
882 0xa2, 0x00,
883 0xb0, 0x91,
884 0xb1, 0x0b,
885 0xc0, 0x53,
886 0xc1, 0x70,
887 0xc2, 0x12,
888 0xd0, 0x00,
889 0xd1, 0x00,
890 0xd2, 0x00,
891 0xd3, 0x00,
892 0xd4, 0x00,
893 0xd5, 0x00,
894 0xde, 0x00,
895 0xdf, 0x00,
896 0x61, 0x38,
897 0x62, 0x0a,
898 0x53, 0x13,
899 0x59, 0x08,
900 0xff, 0xff,
901};
902
903static struct stv0297_config dvbc_philips_tdm1316l_config = {
904 .demod_address = 0x1c,
905 .inittab = dvbc_philips_tdm1316l_inittab,
906 .invert = 0,
907 .pll_set = dvbc_philips_tdm1316l_pll_set,
908};
909
910
1da177e4
LT
911
912
913static void frontend_init(struct budget_ci *budget_ci)
914{
915 switch (budget_ci->budget.dev->pci->subsystem_device) {
916 case 0x100c: // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
917 budget_ci->budget.dvb_frontend =
918 stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap);
919 if (budget_ci->budget.dvb_frontend) {
920 break;
921 }
922 break;
923
924 case 0x100f: // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
925 budget_ci->budget.dvb_frontend =
926 stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
927 if (budget_ci->budget.dvb_frontend) {
928 break;
929 }
930 break;
931
dc27a169
AQ
932 case 0x1010: // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
933 budget_ci->tuner_pll_address = 0x61;
934 budget_ci->budget.dvb_frontend =
935 stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
936 if (budget_ci->budget.dvb_frontend) {
937 break;
938 }
939 break;
940
1da177e4 941 case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
dd2bbb17 942 budget_ci->tuner_pll_address = 0x63;
1da177e4
LT
943 budget_ci->budget.dvb_frontend =
944 tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
945 if (budget_ci->budget.dvb_frontend) {
946 break;
947 }
948 break;
dd2bbb17 949
dc27a169 950 case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
dd2bbb17
AQ
951 budget_ci->tuner_pll_address = 0x60;
952 budget_ci->budget.dvb_frontend =
953 tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
954 if (budget_ci->budget.dvb_frontend) {
955 break;
956 }
957 break;
8cc2e377
PA
958
959 case 0x1017: // TT S-1500 PCI
960 budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap);
961 if (budget_ci->budget.dvb_frontend) {
962 budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
963 if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) {
964 printk("%s: No LNBP21 found!\n", __FUNCTION__);
965 if (budget_ci->budget.dvb_frontend->ops->release)
966 budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend);
967 budget_ci->budget.dvb_frontend = NULL;
968 }
969 }
970
971 break;
1da177e4
LT
972 }
973
974 if (budget_ci->budget.dvb_frontend == NULL) {
975 printk("budget-ci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
976 budget_ci->budget.dev->pci->vendor,
977 budget_ci->budget.dev->pci->device,
978 budget_ci->budget.dev->pci->subsystem_vendor,
979 budget_ci->budget.dev->pci->subsystem_device);
980 } else {
981 if (dvb_register_frontend
fdc53a6d 982 (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
1da177e4
LT
983 printk("budget-ci: Frontend registration failed!\n");
984 if (budget_ci->budget.dvb_frontend->ops->release)
985 budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend);
986 budget_ci->budget.dvb_frontend = NULL;
987 }
988 }
989}
990
991static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
992{
993 struct budget_ci *budget_ci;
994 int err;
995
996 if (!(budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL)))
997 return -ENOMEM;
998
999 dprintk(2, "budget_ci: %p\n", budget_ci);
1000
1001 budget_ci->budget.ci_present = 0;
1002
1003 dev->ext_priv = budget_ci;
1004
1005 if ((err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE))) {
1006 kfree(budget_ci);
1007 return err;
1008 }
1009
1010 tasklet_init(&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt,
1011 (unsigned long) budget_ci);
1012
1013 msp430_ir_init(budget_ci);
1014
1015 ciintf_init(budget_ci);
1016
fdc53a6d 1017 budget_ci->budget.dvb_adapter.priv = budget_ci;
1da177e4
LT
1018 frontend_init(budget_ci);
1019
1020 return 0;
1021}
1022
1023static int budget_ci_detach(struct saa7146_dev *dev)
1024{
1025 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
1026 struct saa7146_dev *saa = budget_ci->budget.dev;
1027 int err;
1028
1029 if (budget_ci->budget.ci_present)
1030 ciintf_deinit(budget_ci);
1031 if (budget_ci->budget.dvb_frontend)
1032 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
1033 err = ttpci_budget_deinit(&budget_ci->budget);
1034
1035 tasklet_kill(&budget_ci->msp430_irq_tasklet);
1036
1037 msp430_ir_deinit(budget_ci);
1038
1039 // disable frontend and CI interface
1040 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1041
1042 kfree(budget_ci);
1043
1044 return err;
1045}
1046
1047static struct saa7146_extension budget_extension;
1048
8cc2e377 1049MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
1da177e4
LT
1050MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1051MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
dd2bbb17 1052MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
dc27a169 1053MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1da177e4
LT
1054
1055static struct pci_device_id pci_tbl[] = {
1056 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
1057 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
dc27a169 1058 MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
1da177e4 1059 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
dd2bbb17 1060 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
8cc2e377 1061 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1da177e4
LT
1062 {
1063 .vendor = 0,
1064 }
1065};
1066
1067MODULE_DEVICE_TABLE(pci, pci_tbl);
1068
1069static struct saa7146_extension budget_extension = {
1070 .name = "budget_ci dvb\0",
69459f3d 1071 .flags = SAA7146_I2C_SHORT_DELAY,
1da177e4
LT
1072
1073 .module = THIS_MODULE,
1074 .pci_tbl = &pci_tbl[0],
1075 .attach = budget_ci_attach,
1076 .detach = budget_ci_detach,
1077
1078 .irq_mask = MASK_03 | MASK_06 | MASK_10,
1079 .irq_func = budget_ci_irq,
1080};
1081
1082static int __init budget_ci_init(void)
1083{
1084 return saa7146_register_extension(&budget_extension);
1085}
1086
1087static void __exit budget_ci_exit(void)
1088{
1089 saa7146_unregister_extension(&budget_extension);
1090}
1091
1092module_init(budget_ci_init);
1093module_exit(budget_ci_exit);
1094
1095MODULE_LICENSE("GPL");
1096MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1097MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1098 "budget PCI DVB cards w/ CI-module produced by "
1099 "Siemens, Technotrend, Hauppauge");
This page took 0.214987 seconds and 5 git commands to generate.