ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-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 "dvb_functions.h"
39
40 static void Set22K (struct budget *budget, int state)
41 {
42         struct saa7146_dev *dev=budget->dev;
43         DEB_EE(("budget: %p\n",budget));
44         saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
45 }
46
47
48 /* Diseqc functions only for TT Budget card */
49 /* taken from the Skyvision DVB driver by
50    Ralph Metzler <rjkm@metzlerbros.de> */
51
52 static void DiseqcSendBit (struct budget *budget, int data)
53 {
54         struct saa7146_dev *dev=budget->dev;
55         DEB_EE(("budget: %p\n",budget));
56
57         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
58         udelay(data ? 500 : 1000);
59         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
60         udelay(data ? 1000 : 500);
61 }
62
63
64 static void DiseqcSendByte (struct budget *budget, int data)
65 {
66         int i, par=1, d;
67
68         DEB_EE(("budget: %p\n",budget));
69
70         for (i=7; i>=0; i--) {
71                 d = (data>>i)&1;
72                 par ^= d;
73                 DiseqcSendBit(budget, d);
74         }
75
76         DiseqcSendBit(budget, par);
77 }
78
79
80 static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
81 {
82         struct saa7146_dev *dev=budget->dev;
83         int i;
84
85         DEB_EE(("budget: %p\n",budget));
86
87         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
88         mdelay(16);
89
90         for (i=0; i<len; i++)
91                 DiseqcSendByte(budget, msg[i]);
92
93         mdelay(16);
94
95         if (burst!=-1) {
96                 if (burst)
97                         DiseqcSendByte(budget, 0xff);
98                 else {
99                         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
100                         udelay(12500);
101                         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
102                 }
103                 dvb_delay(20);
104         }
105
106         return 0;
107 }
108
109
110 int budget_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
111 {
112        struct budget *budget = fe->before_after_data;
113
114        DEB_EE(("budget: %p\n",budget));
115
116        switch (cmd) {
117        case FE_SET_TONE:
118                switch ((fe_sec_tone_mode_t) arg) {
119                case SEC_TONE_ON:
120                        Set22K (budget, 1);
121                        break;
122                case SEC_TONE_OFF:
123                        Set22K (budget, 0);
124                        break;
125                default:
126                        return -EINVAL;
127                };
128                break;
129
130        case FE_DISEQC_SEND_MASTER_CMD:
131        {
132                struct dvb_diseqc_master_cmd *cmd = arg;
133
134                SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
135                break;
136        }
137
138        case FE_DISEQC_SEND_BURST:
139                SendDiSEqCMsg (budget, 0, NULL, (unsigned long)arg);
140                break;
141
142        default:
143                return -EOPNOTSUPP;
144        };
145
146        return 0;
147 }
148
149
150 /*
151  *   Routines for the Fujitsu Siemens Activy budget card
152  *   22 kHz tone and DiSEqC are handled by the frontend.
153  *   Voltage must be set here.
154  */
155 static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage)
156 {
157         struct saa7146_dev *dev=budget->dev;
158
159         DEB_EE(("budget: %p\n",budget));
160
161         switch (voltage) {
162                 case SEC_VOLTAGE_13:
163                         saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO);
164                         break;
165                 case SEC_VOLTAGE_18:
166                         saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
167                         break;
168                 default:
169                         return -EINVAL;
170         }
171
172         return 0;
173 }
174
175
176 static int budget_ioctl_activy (struct dvb_frontend *fe, unsigned int cmd, void *arg)
177 {
178         struct budget *budget = fe->before_after_data;
179
180         DEB_EE(("budget: %p\n",budget));
181
182         switch (cmd) {
183                 case FE_SET_VOLTAGE:
184                         return SetVoltage_Activy (budget, (fe_sec_voltage_t) arg);
185                 default:
186                         return -EOPNOTSUPP;
187         }
188
189         return 0;
190 }
191
192
193 static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
194 {
195         struct budget *budget = NULL;
196         int err;
197
198         budget = kmalloc(sizeof(struct budget), GFP_KERNEL);
199         if( NULL == budget ) {
200                 return -ENOMEM;
201         }
202
203         DEB_EE(("dev:%p, info:%p, budget:%p\n",dev,info,budget));
204
205         if ((err = ttpci_budget_init (budget, dev, info))) {
206                 printk("==> failed\n");
207                 kfree (budget);
208                 return err;
209         }
210
211         if (budget->card->type == BUDGET_FS_ACTIVY)
212                 dvb_add_frontend_ioctls (budget->dvb_adapter,
213                                  budget_ioctl_activy, NULL, budget);
214         else
215         dvb_add_frontend_ioctls (budget->dvb_adapter,
216                                  budget_diseqc_ioctl, NULL, budget);
217
218         dev->ext_priv = budget;
219
220         return 0;
221 }
222
223
224 static int budget_detach (struct saa7146_dev* dev)
225 {
226         struct budget *budget = (struct budget*) dev->ext_priv;
227         int err;
228
229         if (budget->card->type == BUDGET_FS_ACTIVY)
230                 dvb_remove_frontend_ioctls (budget->dvb_adapter,
231                                     budget_ioctl_activy, NULL);
232         else
233         dvb_remove_frontend_ioctls (budget->dvb_adapter,
234                                     budget_diseqc_ioctl, NULL);
235
236         err = ttpci_budget_deinit (budget);
237
238         kfree (budget);
239         dev->ext_priv = NULL;
240
241         return err;
242 }
243
244
245
246 static struct saa7146_extension budget_extension;
247
248 MAKE_BUDGET_INFO(ttbs,  "TT-Budget/WinTV-NOVA-S  PCI",  BUDGET_TT);
249 MAKE_BUDGET_INFO(ttbc,  "TT-Budget/WinTV-NOVA-C  PCI",  BUDGET_TT);
250 MAKE_BUDGET_INFO(ttbt,  "TT-Budget/WinTV-NOVA-T  PCI",  BUDGET_TT);
251 MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI",       BUDGET_TT_HW_DISEQC);
252 MAKE_BUDGET_INFO(fsacs, "Fujitsu Siemens Activy Budget-S PCI", BUDGET_FS_ACTIVY);
253 /* Uncomment for Budget Patch */
254 /*MAKE_BUDGET_INFO(fs_1_3,"Siemens/Technotrend/Hauppauge PCI rev1.3+Budget_Patch", BUDGET_PATCH);*/
255
256 static struct pci_device_id pci_tbl[] = {
257         /* Uncomment for Budget Patch */
258         /*MAKE_EXTENSION_PCI(fs_1_3,0x13c2, 0x0000),*/
259         MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1003),
260         MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
261         MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),
262         MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
263         MAKE_EXTENSION_PCI(fsacs, 0x1131, 0x4f61),
264         {
265                 .vendor    = 0,
266         }
267 };
268
269 MODULE_DEVICE_TABLE(pci, pci_tbl);
270
271 static struct saa7146_extension budget_extension = {
272         .name           = "budget dvb\0",
273         .flags          = 0,
274         
275         .module         = THIS_MODULE,
276         .pci_tbl        = pci_tbl,
277         .attach         = budget_attach,
278         .detach         = budget_detach,
279
280         .irq_mask       = MASK_10,
281         .irq_func       = ttpci_budget_irq10_handler,
282 };      
283
284
285 static int __init budget_init(void) 
286 {
287         return saa7146_register_extension(&budget_extension);
288 }
289
290
291 static void __exit budget_exit(void)
292 {
293         DEB_EE((".\n"));
294         saa7146_unregister_extension(&budget_extension); 
295 }
296
297 module_init(budget_init);
298 module_exit(budget_exit);
299
300 MODULE_LICENSE("GPL");
301 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
302 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
303                    "budget PCI DVB cards by Siemens, Technotrend, Hauppauge");
304