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