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