V4L/DVB (3404): Refactored LNBP21 and BSBE1 support
[deliverable/linux.git] / drivers / media / dvb / ttpci / budget.c
1 /*
2 * budget.c: driver for the SAA7146 based Budget DVB cards
3 *
4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
5 *
6 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
7 *
8 * Copyright (C) 1999-2002 Ralph Metzler
9 * & Marcus Metzler for convergence integrated media GmbH
10 *
11 * 26feb2004 Support for FS Activy Card (Grundig tuner) by
12 * Michael Dreher <michael@5dot1.de>,
13 * Oliver Endriss <o.endriss@gmx.de> and
14 * Andreas 'randy' Weinberger
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
32 *
33 *
34 * the project's page is at http://www.linuxtv.org/dvb/
35 */
36
37 #include "budget.h"
38 #include "stv0299.h"
39 #include "ves1x93.h"
40 #include "ves1820.h"
41 #include "l64781.h"
42 #include "tda8083.h"
43 #include "s5h1420.h"
44 #include "lnbp21.h"
45 #include "bsbe1.h"
46
47 static void Set22K (struct budget *budget, int state)
48 {
49 struct saa7146_dev *dev=budget->dev;
50 dprintk(2, "budget: %p\n", budget);
51 saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
52 }
53
54 /* Diseqc functions only for TT Budget card */
55 /* taken from the Skyvision DVB driver by
56 Ralph Metzler <rjkm@metzlerbros.de> */
57
58 static void DiseqcSendBit (struct budget *budget, int data)
59 {
60 struct saa7146_dev *dev=budget->dev;
61 dprintk(2, "budget: %p\n", budget);
62
63 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
64 udelay(data ? 500 : 1000);
65 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
66 udelay(data ? 1000 : 500);
67 }
68
69 static void DiseqcSendByte (struct budget *budget, int data)
70 {
71 int i, par=1, d;
72
73 dprintk(2, "budget: %p\n", budget);
74
75 for (i=7; i>=0; i--) {
76 d = (data>>i)&1;
77 par ^= d;
78 DiseqcSendBit(budget, d);
79 }
80
81 DiseqcSendBit(budget, par);
82 }
83
84 static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
85 {
86 struct saa7146_dev *dev=budget->dev;
87 int i;
88
89 dprintk(2, "budget: %p\n", budget);
90
91 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
92 mdelay(16);
93
94 for (i=0; i<len; i++)
95 DiseqcSendByte(budget, msg[i]);
96
97 mdelay(16);
98
99 if (burst!=-1) {
100 if (burst)
101 DiseqcSendByte(budget, 0xff);
102 else {
103 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
104 udelay(12500);
105 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
106 }
107 msleep(20);
108 }
109
110 return 0;
111 }
112
113 /*
114 * Routines for the Fujitsu Siemens Activy budget card
115 * 22 kHz tone and DiSEqC are handled by the frontend.
116 * Voltage must be set here.
117 * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL
118 */
119 static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage)
120 {
121 struct saa7146_dev *dev=budget->dev;
122
123 dprintk(2, "budget: %p\n", budget);
124
125 switch (voltage) {
126 case SEC_VOLTAGE_13:
127 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
128 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO);
129 break;
130 case SEC_VOLTAGE_18:
131 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
132 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
133 break;
134 case SEC_VOLTAGE_OFF:
135 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO);
136 break;
137 default:
138 return -EINVAL;
139 }
140
141 return 0;
142 }
143
144 static int siemens_budget_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
145 {
146 struct budget* budget = (struct budget*) fe->dvb->priv;
147
148 return SetVoltage_Activy (budget, voltage);
149 }
150
151 static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
152 {
153 struct budget* budget = (struct budget*) fe->dvb->priv;
154
155 switch (tone) {
156 case SEC_TONE_ON:
157 Set22K (budget, 1);
158 break;
159
160 case SEC_TONE_OFF:
161 Set22K (budget, 0);
162 break;
163
164 default:
165 return -EINVAL;
166 }
167
168 return 0;
169 }
170
171 static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
172 {
173 struct budget* budget = (struct budget*) fe->dvb->priv;
174
175 SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
176
177 return 0;
178 }
179
180 static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
181 {
182 struct budget* budget = (struct budget*) fe->dvb->priv;
183
184 SendDiSEqCMsg (budget, 0, NULL, minicmd);
185
186 return 0;
187 }
188
189 static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
190 {
191 struct budget* budget = (struct budget*) fe->dvb->priv;
192 u8 pwr = 0;
193 u8 buf[4];
194 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
195 u32 div = (params->frequency + 479500) / 125;
196
197 if (params->frequency > 2000000) pwr = 3;
198 else if (params->frequency > 1800000) pwr = 2;
199 else if (params->frequency > 1600000) pwr = 1;
200 else if (params->frequency > 1200000) pwr = 0;
201 else if (params->frequency >= 1100000) pwr = 1;
202 else pwr = 2;
203
204 buf[0] = (div >> 8) & 0x7f;
205 buf[1] = div & 0xff;
206 buf[2] = ((div & 0x18000) >> 10) | 0x95;
207 buf[3] = (pwr << 6) | 0x30;
208
209 // NOTE: since we're using a prescaler of 2, we set the
210 // divisor frequency to 62.5kHz and divide by 125 above
211
212 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
213 return 0;
214 }
215
216 static struct ves1x93_config alps_bsrv2_config =
217 {
218 .demod_address = 0x08,
219 .xin = 90100000UL,
220 .invert_pwm = 0,
221 .pll_set = alps_bsrv2_pll_set,
222 };
223
224 static u8 alps_bsru6_inittab[] = {
225 0x01, 0x15,
226 0x02, 0x00,
227 0x03, 0x00,
228 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
229 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
230 0x06, 0x40, /* DAC not used, set to high impendance mode */
231 0x07, 0x00, /* DAC LSB */
232 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
233 0x09, 0x00, /* FIFO */
234 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
235 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
236 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
237 0x10, 0x3f, // AGC2 0x3d
238 0x11, 0x84,
239 0x12, 0xb9,
240 0x15, 0xc9, // lock detector threshold
241 0x16, 0x00,
242 0x17, 0x00,
243 0x18, 0x00,
244 0x19, 0x00,
245 0x1a, 0x00,
246 0x1f, 0x50,
247 0x20, 0x00,
248 0x21, 0x00,
249 0x22, 0x00,
250 0x23, 0x00,
251 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
252 0x29, 0x1e, // 1/2 threshold
253 0x2a, 0x14, // 2/3 threshold
254 0x2b, 0x0f, // 3/4 threshold
255 0x2c, 0x09, // 5/6 threshold
256 0x2d, 0x05, // 7/8 threshold
257 0x2e, 0x01,
258 0x31, 0x1f, // test all FECs
259 0x32, 0x19, // viterbi and synchro search
260 0x33, 0xfc, // rs control
261 0x34, 0x93, // error control
262 0x0f, 0x52,
263 0xff, 0xff
264 };
265
266 static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
267 {
268 u8 aclk = 0;
269 u8 bclk = 0;
270
271 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
272 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
273 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
274 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
275 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
276 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
277
278 stv0299_writereg (fe, 0x13, aclk);
279 stv0299_writereg (fe, 0x14, bclk);
280 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
281 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
282 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
283
284 return 0;
285 }
286
287 static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
288 {
289 u8 data[4];
290 u32 div;
291 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
292
293 if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL;
294
295 div = (params->frequency + (125 - 1)) / 125; // round correctly
296 data[0] = (div >> 8) & 0x7f;
297 data[1] = div & 0xff;
298 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
299 data[3] = 0xC4;
300
301 if (params->frequency > 1530000) data[3] = 0xc0;
302
303 if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
304 return 0;
305 }
306
307 static struct stv0299_config alps_bsru6_config = {
308
309 .demod_address = 0x68,
310 .inittab = alps_bsru6_inittab,
311 .mclk = 88000000UL,
312 .invert = 1,
313 .skip_reinit = 0,
314 .lock_output = STV0229_LOCKOUTPUT_1,
315 .volt13_op0_op1 = STV0299_VOLT13_OP1,
316 .min_delay_ms = 100,
317 .set_symbol_rate = alps_bsru6_set_symbol_rate,
318 .pll_set = alps_bsru6_pll_set,
319 };
320
321 static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
322 {
323 struct budget* budget = (struct budget*) fe->dvb->priv;
324 u32 div;
325 u8 data[4];
326 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
327
328 div = (params->frequency + 35937500 + 31250) / 62500;
329
330 data[0] = (div >> 8) & 0x7f;
331 data[1] = div & 0xff;
332 data[2] = 0x85 | ((div >> 10) & 0x60);
333 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
334
335 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
336 return 0;
337 }
338
339 static struct ves1820_config alps_tdbe2_config = {
340 .demod_address = 0x09,
341 .xin = 57840000UL,
342 .invert = 1,
343 .selagc = VES1820_SELAGC_SIGNAMPERR,
344 .pll_set = alps_tdbe2_pll_set,
345 };
346
347 static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
348 {
349 struct budget* budget = (struct budget*) fe->dvb->priv;
350 u32 div;
351 u8 cfg, cpump, band_select;
352 u8 data[4];
353 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
354
355 div = (36125000 + params->frequency) / 166666;
356
357 cfg = 0x88;
358
359 if (params->frequency < 175000000) cpump = 2;
360 else if (params->frequency < 390000000) cpump = 1;
361 else if (params->frequency < 470000000) cpump = 2;
362 else if (params->frequency < 750000000) cpump = 1;
363 else cpump = 3;
364
365 if (params->frequency < 175000000) band_select = 0x0e;
366 else if (params->frequency < 470000000) band_select = 0x05;
367 else band_select = 0x03;
368
369 data[0] = (div >> 8) & 0x7f;
370 data[1] = div & 0xff;
371 data[2] = ((div >> 10) & 0x60) | cfg;
372 data[3] = (cpump << 6) | band_select;
373
374 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
375 return 0;
376 }
377
378 static struct l64781_config grundig_29504_401_config = {
379 .demod_address = 0x55,
380 .pll_set = grundig_29504_401_pll_set,
381 };
382
383 static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
384 {
385 struct budget* budget = (struct budget*) fe->dvb->priv;
386 u32 div;
387 u8 data[4];
388 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
389
390 div = params->frequency / 125;
391 data[0] = (div >> 8) & 0x7f;
392 data[1] = div & 0xff;
393 data[2] = 0x8e;
394 data[3] = 0x00;
395
396 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
397 return 0;
398 }
399
400 static struct tda8083_config grundig_29504_451_config = {
401 .demod_address = 0x68,
402 .pll_set = grundig_29504_451_pll_set,
403 };
404
405 static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout)
406 {
407 struct budget* budget = (struct budget*) fe->dvb->priv;
408 u32 div;
409 u8 data[4];
410 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
411
412 div = params->frequency / 1000;
413 data[0] = (div >> 8) & 0x7f;
414 data[1] = div & 0xff;
415 data[2] = 0xc2;
416
417 if (div < 1450)
418 data[3] = 0x00;
419 else if (div < 1850)
420 data[3] = 0x40;
421 else if (div < 2000)
422 data[3] = 0x80;
423 else
424 data[3] = 0xc0;
425
426 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
427
428 *freqout = div * 1000;
429 return 0;
430 }
431
432 static struct s5h1420_config s5h1420_config = {
433 .demod_address = 0x53,
434 .invert = 1,
435 .pll_set = s5h1420_pll_set,
436 };
437
438 static u8 read_pwm(struct budget* budget)
439 {
440 u8 b = 0xff;
441 u8 pwm;
442 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
443 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
444
445 if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
446 pwm = 0x48;
447
448 return pwm;
449 }
450
451 static void frontend_init(struct budget *budget)
452 {
453 switch(budget->dev->pci->subsystem_device) {
454 case 0x1017:
455 // try the ALPS BSBE1 now
456 budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap);
457 if (budget->dvb_frontend) {
458 budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
459 if (lnbp21_init(budget->dvb_frontend, &budget->i2c_adap, LNBP21_LLC, 0)) {
460 printk("%s: No LNBP21 found!\n", __FUNCTION__);
461 goto error_out;
462 }
463 }
464
465 break;
466 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
467 case 0x1013:
468 // try the ALPS BSRV2 first of all
469 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
470 if (budget->dvb_frontend) {
471 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
472 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
473 budget->dvb_frontend->ops->set_tone = budget_set_tone;
474 break;
475 }
476
477 // try the ALPS BSRU6 now
478 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
479 if (budget->dvb_frontend) {
480 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
481 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
482 budget->dvb_frontend->ops->set_tone = budget_set_tone;
483 break;
484 }
485 break;
486
487 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
488
489 budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget));
490 if (budget->dvb_frontend) break;
491 break;
492
493 case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060))
494
495 budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap);
496 if (budget->dvb_frontend) break;
497 break;
498
499 case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059))
500 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
501 if (budget->dvb_frontend) {
502 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
503 budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
504 }
505 break;
506
507 case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522))
508 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
509 if (budget->dvb_frontend) {
510 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
511 budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
512 }
513 break;
514
515 case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260))
516 budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap);
517 if (budget->dvb_frontend) {
518 if (lnbp21_init(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) {
519 printk("%s: No LNBP21 found!\n", __FUNCTION__);
520 goto error_out;
521 }
522 break;
523 }
524 }
525
526 if (budget->dvb_frontend == NULL) {
527 printk("budget: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
528 budget->dev->pci->vendor,
529 budget->dev->pci->device,
530 budget->dev->pci->subsystem_vendor,
531 budget->dev->pci->subsystem_device);
532 } else {
533 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend))
534 goto error_out;
535 }
536 return;
537
538 error_out:
539 printk("budget: Frontend registration failed!\n");
540 if (budget->dvb_frontend->ops->release)
541 budget->dvb_frontend->ops->release(budget->dvb_frontend);
542 budget->dvb_frontend = NULL;
543 return;
544 }
545
546 static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
547 {
548 struct budget *budget = NULL;
549 int err;
550
551 budget = kmalloc(sizeof(struct budget), GFP_KERNEL);
552 if( NULL == budget ) {
553 return -ENOMEM;
554 }
555
556 dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget);
557
558 dev->ext_priv = budget;
559
560 if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
561 printk("==> failed\n");
562 kfree (budget);
563 return err;
564 }
565
566 budget->dvb_adapter.priv = budget;
567 frontend_init(budget);
568
569 return 0;
570 }
571
572 static int budget_detach (struct saa7146_dev* dev)
573 {
574 struct budget *budget = (struct budget*) dev->ext_priv;
575 int err;
576
577 if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend);
578
579 err = ttpci_budget_deinit (budget);
580
581 kfree (budget);
582 dev->ext_priv = NULL;
583
584 return err;
585 }
586
587 static struct saa7146_extension budget_extension;
588
589 MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT);
590 MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT);
591 MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
592 MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
593 MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC);
594 MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY);
595 MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
596
597 static struct pci_device_id pci_tbl[] = {
598 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003),
599 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
600 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
601 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
602 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
603 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
604 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
605 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
606 {
607 .vendor = 0,
608 }
609 };
610
611 MODULE_DEVICE_TABLE(pci, pci_tbl);
612
613 static struct saa7146_extension budget_extension = {
614 .name = "budget dvb\0",
615 .flags = SAA7146_I2C_SHORT_DELAY,
616
617 .module = THIS_MODULE,
618 .pci_tbl = pci_tbl,
619 .attach = budget_attach,
620 .detach = budget_detach,
621
622 .irq_mask = MASK_10,
623 .irq_func = ttpci_budget_irq10_handler,
624 };
625
626 static int __init budget_init(void)
627 {
628 return saa7146_register_extension(&budget_extension);
629 }
630
631 static void __exit budget_exit(void)
632 {
633 saa7146_unregister_extension(&budget_extension);
634 }
635
636 module_init(budget_init);
637 module_exit(budget_exit);
638
639 MODULE_LICENSE("GPL");
640 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
641 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
642 "budget PCI DVB cards by Siemens, Technotrend, Hauppauge");
This page took 0.096981 seconds and 5 git commands to generate.