Merge with http://kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[sfrench/cifs-2.6.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
45 static void Set22K (struct budget *budget, int state)
46 {
47         struct saa7146_dev *dev=budget->dev;
48         dprintk(2, "budget: %p\n", budget);
49         saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
50 }
51
52 /* Diseqc functions only for TT Budget card */
53 /* taken from the Skyvision DVB driver by
54    Ralph Metzler <rjkm@metzlerbros.de> */
55
56 static void DiseqcSendBit (struct budget *budget, int data)
57 {
58         struct saa7146_dev *dev=budget->dev;
59         dprintk(2, "budget: %p\n", budget);
60
61         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
62         udelay(data ? 500 : 1000);
63         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
64         udelay(data ? 1000 : 500);
65 }
66
67 static void DiseqcSendByte (struct budget *budget, int data)
68 {
69         int i, par=1, d;
70
71         dprintk(2, "budget: %p\n", budget);
72
73         for (i=7; i>=0; i--) {
74                 d = (data>>i)&1;
75                 par ^= d;
76                 DiseqcSendBit(budget, d);
77         }
78
79         DiseqcSendBit(budget, par);
80 }
81
82 static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
83 {
84         struct saa7146_dev *dev=budget->dev;
85         int i;
86
87         dprintk(2, "budget: %p\n", budget);
88
89         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
90         mdelay(16);
91
92         for (i=0; i<len; i++)
93                 DiseqcSendByte(budget, msg[i]);
94
95         mdelay(16);
96
97         if (burst!=-1) {
98                 if (burst)
99                         DiseqcSendByte(budget, 0xff);
100                 else {
101                         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
102                         udelay(12500);
103                         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
104                 }
105                 msleep(20);
106         }
107
108         return 0;
109 }
110
111 /*
112  *   Routines for the Fujitsu Siemens Activy budget card
113  *   22 kHz tone and DiSEqC are handled by the frontend.
114  *   Voltage must be set here.
115  */
116 static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage)
117 {
118         struct saa7146_dev *dev=budget->dev;
119
120         dprintk(2, "budget: %p\n", budget);
121
122         switch (voltage) {
123                 case SEC_VOLTAGE_13:
124                         saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO);
125                         break;
126                 case SEC_VOLTAGE_18:
127                         saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
128                         break;
129                 default:
130                         return -EINVAL;
131         }
132
133         return 0;
134 }
135
136 static int siemens_budget_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
137 {
138         struct budget* budget = (struct budget*) fe->dvb->priv;
139
140         return SetVoltage_Activy (budget, voltage);
141 }
142
143 static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
144 {
145         struct budget* budget = (struct budget*) fe->dvb->priv;
146
147         switch (tone) {
148         case SEC_TONE_ON:
149                 Set22K (budget, 1);
150                 break;
151
152         case SEC_TONE_OFF:
153                 Set22K (budget, 0);
154                 break;
155
156         default:
157                 return -EINVAL;
158         }
159
160         return 0;
161 }
162
163 static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
164 {
165         struct budget* budget = (struct budget*) fe->dvb->priv;
166
167         SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
168
169         return 0;
170 }
171
172 static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
173 {
174         struct budget* budget = (struct budget*) fe->dvb->priv;
175
176         SendDiSEqCMsg (budget, 0, NULL, minicmd);
177
178         return 0;
179 }
180
181 static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
182 {
183         struct budget* budget = (struct budget*) fe->dvb->priv;
184         u8 buf;
185         struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
186
187         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
188
189         switch(voltage) {
190         case SEC_VOLTAGE_13:
191                 buf = (buf & 0xf7) | 0x04;
192                 break;
193
194         case SEC_VOLTAGE_18:
195                 buf = (buf & 0xf7) | 0x0c;
196                 break;
197
198         case SEC_VOLTAGE_OFF:
199                 buf = buf & 0xf0;
200                 break;
201         }
202
203         msg.flags = 0;
204         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
205
206         return 0;
207 }
208
209 static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg)
210 {
211         struct budget* budget = (struct budget*) fe->dvb->priv;
212         u8 buf;
213         struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
214
215         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
216
217         if (arg) {
218                 buf = buf | 0x10;
219         } else {
220                 buf = buf & 0xef;
221         }
222
223         msg.flags = 0;
224         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
225
226         return 0;
227 }
228
229 static int lnbp21_init(struct budget* budget)
230 {
231         u8 buf = 0x00;
232         struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
233
234         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
235                 return -EIO;
236         return 0;
237 }
238
239 static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
240 {
241         struct budget* budget = (struct budget*) fe->dvb->priv;
242         u8 pwr = 0;
243         u8 buf[4];
244         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
245         u32 div = (params->frequency + 479500) / 125;
246
247         if (params->frequency > 2000000) pwr = 3;
248         else if (params->frequency > 1800000) pwr = 2;
249         else if (params->frequency > 1600000) pwr = 1;
250         else if (params->frequency > 1200000) pwr = 0;
251         else if (params->frequency >= 1100000) pwr = 1;
252         else pwr = 2;
253
254         buf[0] = (div >> 8) & 0x7f;
255         buf[1] = div & 0xff;
256         buf[2] = ((div & 0x18000) >> 10) | 0x95;
257         buf[3] = (pwr << 6) | 0x30;
258
259         // NOTE: since we're using a prescaler of 2, we set the
260         // divisor frequency to 62.5kHz and divide by 125 above
261
262         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
263         return 0;
264 }
265
266 static struct ves1x93_config alps_bsrv2_config =
267 {
268         .demod_address = 0x08,
269         .xin = 90100000UL,
270         .invert_pwm = 0,
271         .pll_set = alps_bsrv2_pll_set,
272 };
273
274 static u8 alps_bsru6_inittab[] = {
275         0x01, 0x15,
276         0x02, 0x00,
277         0x03, 0x00,
278         0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
279         0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
280         0x06, 0x40,   /* DAC not used, set to high impendance mode */
281         0x07, 0x00,   /* DAC LSB */
282         0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
283         0x09, 0x00,   /* FIFO */
284         0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
285         0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
286         0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
287         0x10, 0x3f,   // AGC2  0x3d
288         0x11, 0x84,
289         0x12, 0xb9,
290         0x15, 0xc9,   // lock detector threshold
291         0x16, 0x00,
292         0x17, 0x00,
293         0x18, 0x00,
294         0x19, 0x00,
295         0x1a, 0x00,
296         0x1f, 0x50,
297         0x20, 0x00,
298         0x21, 0x00,
299         0x22, 0x00,
300         0x23, 0x00,
301         0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
302         0x29, 0x1e,  // 1/2 threshold
303         0x2a, 0x14,  // 2/3 threshold
304         0x2b, 0x0f,  // 3/4 threshold
305         0x2c, 0x09,  // 5/6 threshold
306         0x2d, 0x05,  // 7/8 threshold
307         0x2e, 0x01,
308         0x31, 0x1f,  // test all FECs
309         0x32, 0x19,  // viterbi and synchro search
310         0x33, 0xfc,  // rs control
311         0x34, 0x93,  // error control
312         0x0f, 0x52,
313         0xff, 0xff
314 };
315
316 static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
317 {
318         u8 aclk = 0;
319         u8 bclk = 0;
320
321         if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
322         else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
323         else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
324         else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
325         else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
326         else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
327
328         stv0299_writereg (fe, 0x13, aclk);
329         stv0299_writereg (fe, 0x14, bclk);
330         stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
331         stv0299_writereg (fe, 0x20, (ratio >>  8) & 0xff);
332         stv0299_writereg (fe, 0x21, (ratio      ) & 0xf0);
333
334         return 0;
335 }
336
337 static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
338 {
339         u8 data[4];
340         u32 div;
341         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
342
343         if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL;
344
345         div = (params->frequency + (125 - 1)) / 125; // round correctly
346         data[0] = (div >> 8) & 0x7f;
347         data[1] = div & 0xff;
348         data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
349         data[3] = 0xC4;
350
351         if (params->frequency > 1530000) data[3] = 0xc0;
352
353         if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
354         return 0;
355 }
356
357 static struct stv0299_config alps_bsru6_config = {
358
359         .demod_address = 0x68,
360         .inittab = alps_bsru6_inittab,
361         .mclk = 88000000UL,
362         .invert = 1,
363         .skip_reinit = 0,
364         .lock_output = STV0229_LOCKOUTPUT_1,
365         .volt13_op0_op1 = STV0299_VOLT13_OP1,
366         .min_delay_ms = 100,
367         .set_symbol_rate = alps_bsru6_set_symbol_rate,
368         .pll_set = alps_bsru6_pll_set,
369 };
370
371 static u8 alps_bsbe1_inittab[] = {
372         0x01, 0x15,
373         0x02, 0x30,
374         0x03, 0x00,
375         0x04, 0x7d,  /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
376         0x05, 0x35,  /* I2CT = 0, SCLT = 1, SDAT = 1 */
377         0x06, 0x40,  /* DAC not used, set to high impendance mode */
378         0x07, 0x00,  /* DAC LSB */
379         0x08, 0x40,  /* DiSEqC off, LNB power on OP2/LOCK pin on */
380         0x09, 0x00,  /* FIFO */
381         0x0c, 0x51,  /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
382         0x0d, 0x82,  /* DC offset compensation = ON, beta_agc1 = 2 */
383         0x0e, 0x23,  /* alpha_tmg = 2, beta_tmg = 3 */
384         0x10, 0x3f,  // AGC2 0x3d
385         0x11, 0x84,
386         0x12, 0xb9,
387         0x15, 0xc9,  // lock detector threshold
388         0x16, 0x00,
389         0x17, 0x00,
390         0x18, 0x00,
391         0x19, 0x00,
392         0x1a, 0x00,
393         0x1f, 0x50,
394         0x20, 0x00,
395         0x21, 0x00,
396         0x22, 0x00,
397         0x23, 0x00,
398         0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
399         0x29, 0x1e, // 1/2 threshold
400         0x2a, 0x14, // 2/3 threshold
401         0x2b, 0x0f, // 3/4 threshold
402         0x2c, 0x09, // 5/6 threshold
403         0x2d, 0x05, // 7/8 threshold
404         0x2e, 0x01,
405         0x31, 0x1f, // test all FECs
406         0x32, 0x19, // viterbi and synchro search
407         0x33, 0xfc, // rs control
408         0x34, 0x93, // error control
409         0x0f, 0x92, // 0x80 = inverse AGC
410         0xff, 0xff
411 };
412
413 static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
414 {
415         int ret;
416         u8 data[4];
417         u32 div;
418         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
419
420         if ((params->frequency < 950000) || (params->frequency > 2150000))
421                 return -EINVAL;
422
423         div = (params->frequency + (125 - 1)) / 125; // round correctly
424         data[0] = (div >> 8) & 0x7f;
425         data[1] = div & 0xff;
426         data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
427         data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
428
429         ret = i2c_transfer(i2c, &msg, 1);
430         return (ret != 1) ? -EIO : 0;
431 }
432
433 static struct stv0299_config alps_bsbe1_config = {
434         .demod_address = 0x68,
435         .inittab = alps_bsbe1_inittab,
436         .mclk = 88000000UL,
437         .invert = 1,
438         .skip_reinit = 0,
439         .min_delay_ms = 100,
440         .set_symbol_rate = alps_bsru6_set_symbol_rate,
441         .pll_set = alps_bsbe1_pll_set,
442 };
443
444 static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
445 {
446         struct budget* budget = (struct budget*) fe->dvb->priv;
447         u32 div;
448         u8 data[4];
449         struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
450
451         div = (params->frequency + 35937500 + 31250) / 62500;
452
453         data[0] = (div >> 8) & 0x7f;
454         data[1] = div & 0xff;
455         data[2] = 0x85 | ((div >> 10) & 0x60);
456         data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
457
458         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
459         return 0;
460 }
461
462 static struct ves1820_config alps_tdbe2_config = {
463         .demod_address = 0x09,
464         .xin = 57840000UL,
465         .invert = 1,
466         .selagc = VES1820_SELAGC_SIGNAMPERR,
467         .pll_set = alps_tdbe2_pll_set,
468 };
469
470 static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
471 {
472         struct budget* budget = (struct budget*) fe->dvb->priv;
473         u32 div;
474         u8 cfg, cpump, band_select;
475         u8 data[4];
476         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
477
478         div = (36125000 + params->frequency) / 166666;
479
480         cfg = 0x88;
481
482         if (params->frequency < 175000000) cpump = 2;
483         else if (params->frequency < 390000000) cpump = 1;
484         else if (params->frequency < 470000000) cpump = 2;
485         else if (params->frequency < 750000000) cpump = 1;
486         else cpump = 3;
487
488         if (params->frequency < 175000000) band_select = 0x0e;
489         else if (params->frequency < 470000000) band_select = 0x05;
490         else band_select = 0x03;
491
492         data[0] = (div >> 8) & 0x7f;
493         data[1] = div & 0xff;
494         data[2] = ((div >> 10) & 0x60) | cfg;
495         data[3] = (cpump << 6) | band_select;
496
497         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
498         return 0;
499 }
500
501 static struct l64781_config grundig_29504_401_config = {
502         .demod_address = 0x55,
503         .pll_set = grundig_29504_401_pll_set,
504 };
505
506 static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
507 {
508         struct budget* budget = (struct budget*) fe->dvb->priv;
509         u32 div;
510         u8 data[4];
511         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
512
513         div = params->frequency / 125;
514         data[0] = (div >> 8) & 0x7f;
515         data[1] = div & 0xff;
516         data[2] = 0x8e;
517         data[3] = 0x00;
518
519         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
520         return 0;
521 }
522
523 static struct tda8083_config grundig_29504_451_config = {
524         .demod_address = 0x68,
525         .pll_set = grundig_29504_451_pll_set,
526 };
527
528 static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout)
529 {
530         struct budget* budget = (struct budget*) fe->dvb->priv;
531         u32 div;
532         u8 data[4];
533         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
534
535         div = params->frequency / 1000;
536         data[0] = (div >> 8) & 0x7f;
537         data[1] = div & 0xff;
538         data[2] = 0xc2;
539
540         if (div < 1450)
541                 data[3] = 0x00;
542         else if (div < 1850)
543                 data[3] = 0x40;
544         else if (div < 2000)
545                 data[3] = 0x80;
546         else
547                 data[3] = 0xc0;
548
549         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
550
551         *freqout = div * 1000;
552         return 0;
553 }
554
555 static struct s5h1420_config s5h1420_config = {
556         .demod_address = 0x53,
557         .invert = 1,
558         .pll_set = s5h1420_pll_set,
559 };
560
561 static u8 read_pwm(struct budget* budget)
562 {
563         u8 b = 0xff;
564         u8 pwm;
565         struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
566                                  { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
567
568         if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
569                 pwm = 0x48;
570
571         return pwm;
572 }
573
574 static void frontend_init(struct budget *budget)
575 {
576         switch(budget->dev->pci->subsystem_device) {
577         case 0x1017:
578                 // try the ALPS BSBE1 now
579                 budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap);
580                 if (budget->dvb_frontend) {
581                         budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
582                         budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
583                         if (lnbp21_init(budget)) {
584                                 printk("%s: No LNBP21 found!\n", __FUNCTION__);
585                                 goto error_out;
586                         }
587                 }
588
589                 break;
590         case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
591         case 0x1013:
592                 // try the ALPS BSRV2 first of all
593                 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
594                 if (budget->dvb_frontend) {
595                         budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
596                         budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
597                         budget->dvb_frontend->ops->set_tone = budget_set_tone;
598                         break;
599                 }
600
601                 // try the ALPS BSRU6 now
602                 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
603                 if (budget->dvb_frontend) {
604                         budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
605                         budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
606                         budget->dvb_frontend->ops->set_tone = budget_set_tone;
607                         break;
608                 }
609                 break;
610
611         case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
612
613                 budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget));
614                 if (budget->dvb_frontend) break;
615                 break;
616
617         case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060))
618
619                 budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap);
620                 if (budget->dvb_frontend) break;
621                 break;
622
623         case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059))
624                 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
625                 if (budget->dvb_frontend) {
626                         budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
627                         break;
628                 }
629                 break;
630
631         case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522))
632                 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
633                 if (budget->dvb_frontend) {
634                         budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
635                         break;
636                 }
637                 break;
638
639         case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260))
640                 budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap);
641                 if (budget->dvb_frontend) {
642                         budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
643                         budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
644                         if (lnbp21_init(budget)) {
645                                 printk("%s: No LNBP21 found!\n", __FUNCTION__);
646                                 goto error_out;
647                         }
648                         break;
649                 }
650         }
651
652         if (budget->dvb_frontend == NULL) {
653                 printk("budget: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
654                        budget->dev->pci->vendor,
655                        budget->dev->pci->device,
656                        budget->dev->pci->subsystem_vendor,
657                        budget->dev->pci->subsystem_device);
658         } else {
659                 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend))
660                         goto error_out;
661         }
662         return;
663
664 error_out:
665         printk("budget: Frontend registration failed!\n");
666         if (budget->dvb_frontend->ops->release)
667                 budget->dvb_frontend->ops->release(budget->dvb_frontend);
668         budget->dvb_frontend = NULL;
669         return;
670 }
671
672 static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
673 {
674         struct budget *budget = NULL;
675         int err;
676
677         budget = kmalloc(sizeof(struct budget), GFP_KERNEL);
678         if( NULL == budget ) {
679                 return -ENOMEM;
680         }
681
682         dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget);
683
684         dev->ext_priv = budget;
685
686         if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
687                 printk("==> failed\n");
688                 kfree (budget);
689                 return err;
690         }
691
692         budget->dvb_adapter.priv = budget;
693         frontend_init(budget);
694
695         return 0;
696 }
697
698 static int budget_detach (struct saa7146_dev* dev)
699 {
700         struct budget *budget = (struct budget*) dev->ext_priv;
701         int err;
702
703         if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend);
704
705         err = ttpci_budget_deinit (budget);
706
707         kfree (budget);
708         dev->ext_priv = NULL;
709
710         return err;
711 }
712
713 static struct saa7146_extension budget_extension;
714
715 MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT);
716 MAKE_BUDGET_INFO(ttbs,  "TT-Budget/WinTV-NOVA-S  PCI",  BUDGET_TT);
717 MAKE_BUDGET_INFO(ttbc,  "TT-Budget/WinTV-NOVA-C  PCI",  BUDGET_TT);
718 MAKE_BUDGET_INFO(ttbt,  "TT-Budget/WinTV-NOVA-T  PCI",  BUDGET_TT);
719 MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI",       BUDGET_TT_HW_DISEQC);
720 MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY);
721 MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
722
723 static struct pci_device_id pci_tbl[] = {
724         MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1003),
725         MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
726         MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),
727         MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
728         MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
729         MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1016),
730         MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
731         MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
732         {
733                 .vendor    = 0,
734         }
735 };
736
737 MODULE_DEVICE_TABLE(pci, pci_tbl);
738
739 static struct saa7146_extension budget_extension = {
740         .name           = "budget dvb\0",
741         .flags          = 0,
742
743         .module         = THIS_MODULE,
744         .pci_tbl        = pci_tbl,
745         .attach         = budget_attach,
746         .detach         = budget_detach,
747
748         .irq_mask       = MASK_10,
749         .irq_func       = ttpci_budget_irq10_handler,
750 };
751
752 static int __init budget_init(void)
753 {
754         return saa7146_register_extension(&budget_extension);
755 }
756
757 static void __exit budget_exit(void)
758 {
759         saa7146_unregister_extension(&budget_extension);
760 }
761
762 module_init(budget_init);
763 module_exit(budget_exit);
764
765 MODULE_LICENSE("GPL");
766 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
767 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
768                    "budget PCI DVB cards by Siemens, Technotrend, Hauppauge");