Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/dvrabel/uwb
[linux-2.6] / drivers / staging / meilhaus / me4600_do.c
1 /**
2  * @file me4600_do.c
3  *
4  * @brief ME-4000 digital output subdevice instance.
5  * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6  * @author Guenter Gebhardt
7  * @author Krzysztof Gantzke    (k.gantzke@meilhaus.de)
8  */
9
10 /*
11  * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
12  *
13  * This file is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
26  */
27
28 #ifndef __KERNEL__
29 #  define __KERNEL__
30 #endif
31
32 /*
33  * Includes
34  */
35 #include <linux/module.h>
36
37 #include <linux/slab.h>
38 #include <linux/spinlock.h>
39 #include <linux/io.h>
40 #include <linux/types.h>
41
42 #include "medefines.h"
43 #include "meinternal.h"
44 #include "meerror.h"
45
46 #include "medebug.h"
47 #include "me4600_dio_reg.h"
48 #include "me4600_do.h"
49
50 /*
51  * Defines
52  */
53
54 /*
55  * Functions
56  */
57
58 static int me4600_do_io_reset_subdevice(struct me_subdevice *subdevice,
59                                         struct file *filep, int flags)
60 {
61         me4600_do_subdevice_t *instance;
62         uint32_t mode;
63
64         PDEBUG("executed.\n");
65
66         instance = (me4600_do_subdevice_t *) subdevice;
67
68         if (flags) {
69                 PERROR("Invalid flag specified.\n");
70                 return ME_ERRNO_INVALID_FLAGS;
71         }
72
73         ME_SUBDEVICE_ENTER;
74
75         /* Set port to output mode */
76         spin_lock(&instance->subdevice_lock);
77         spin_lock(instance->ctrl_reg_lock);
78         mode = inl(instance->ctrl_reg);
79         mode &= ~ME4600_DIO_CTRL_BIT_MODE_1;    //0xFFFD
80         mode |= ME4600_DIO_CTRL_BIT_MODE_0;     //0x1
81         outl(mode, instance->ctrl_reg);
82         PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
83                    instance->ctrl_reg - instance->reg_base, mode);
84         spin_unlock(instance->ctrl_reg_lock);
85
86         outl(0, instance->port_reg);
87         PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
88                    instance->port_reg - instance->reg_base, 0);
89         spin_unlock(&instance->subdevice_lock);
90
91         ME_SUBDEVICE_EXIT;
92
93         return ME_ERRNO_SUCCESS;
94 }
95
96 static int me4600_do_io_single_config(me_subdevice_t *subdevice,
97                                       struct file *filep,
98                                       int channel,
99                                       int single_config,
100                                       int ref,
101                                       int trig_chan,
102                                       int trig_type, int trig_edge, int flags)
103 {
104         me4600_do_subdevice_t *instance;
105         int err = ME_ERRNO_SUCCESS;
106         uint32_t mode;
107         int size =
108             flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
109                      | ME_IO_SINGLE_CONFIG_DIO_WORD |
110                      ME_IO_SINGLE_CONFIG_DIO_DWORD);
111
112         PDEBUG("executed.\n");
113
114         instance = (me4600_do_subdevice_t *) subdevice;
115
116         ME_SUBDEVICE_ENTER;
117
118         spin_lock(&instance->subdevice_lock);
119         spin_lock(instance->ctrl_reg_lock);
120         mode = inl(instance->ctrl_reg);
121
122         switch (size) {
123         case ME_IO_SINGLE_CONFIG_NO_FLAGS:
124         case ME_IO_SINGLE_CONFIG_DIO_BYTE:
125                 if (channel == 0) {
126                         if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
127                                 mode &= ~(ME4600_DIO_CTRL_BIT_MODE_0 |
128                                           ME4600_DIO_CTRL_BIT_MODE_1);
129                                 mode |= (ME4600_DIO_CTRL_BIT_MODE_0);
130                         } else if (single_config == ME_SINGLE_CONFIG_DIO_MUX32M) {
131                                 mode &= ~(ME4600_DIO_CTRL_BIT_MODE_0 |
132                                           ME4600_DIO_CTRL_BIT_MODE_1 |
133                                           ME4600_DIO_CTRL_BIT_FUNCTION_0 |
134                                           ME4600_DIO_CTRL_BIT_FUNCTION_1 |
135                                           ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
136
137                                 if (ref == ME_REF_DIO_FIFO_LOW) {
138                                         mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
139                                                  ME4600_DIO_CTRL_BIT_MODE_1 |
140                                                  ME4600_DIO_CTRL_BIT_FUNCTION_1);
141                                 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
142                                         mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
143                                                  ME4600_DIO_CTRL_BIT_MODE_1 |
144                                                  ME4600_DIO_CTRL_BIT_FUNCTION_1
145                                                  |
146                                                  ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
147                                 } else {
148                                         PERROR
149                                             ("Invalid port reference specified.\n");
150                                         err = ME_ERRNO_INVALID_SINGLE_CONFIG;
151                                 }
152                         } else if (single_config ==
153                                    ME_SINGLE_CONFIG_DIO_DEMUX32) {
154                                 mode &=
155                                     ~(ME4600_DIO_CTRL_BIT_MODE_0 |
156                                       ME4600_DIO_CTRL_BIT_MODE_1 |
157                                       ME4600_DIO_CTRL_BIT_FUNCTION_0 |
158                                       ME4600_DIO_CTRL_BIT_FUNCTION_1 |
159                                       ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
160
161                                 if (ref == ME_REF_DIO_FIFO_LOW) {
162                                         mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
163                                                  ME4600_DIO_CTRL_BIT_MODE_1 |
164                                                  ME4600_DIO_CTRL_BIT_FUNCTION_0);
165                                 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
166                                         mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
167                                                  ME4600_DIO_CTRL_BIT_MODE_1 |
168                                                  ME4600_DIO_CTRL_BIT_FUNCTION_0
169                                                  |
170                                                  ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
171                                 } else {
172                                         PERROR
173                                             ("Invalid port reference specified.\n");
174                                         err = ME_ERRNO_INVALID_SINGLE_CONFIG;
175                                 }
176                         } else if (single_config ==
177                                    ME_SINGLE_CONFIG_DIO_BIT_PATTERN) {
178                                 mode &=
179                                     ~(ME4600_DIO_CTRL_BIT_MODE_0 |
180                                       ME4600_DIO_CTRL_BIT_MODE_1 |
181                                       ME4600_DIO_CTRL_BIT_FUNCTION_0 |
182                                       ME4600_DIO_CTRL_BIT_FUNCTION_1 |
183                                       ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
184
185                                 if (ref == ME_REF_DIO_FIFO_LOW) {
186                                         mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
187                                                  ME4600_DIO_CTRL_BIT_MODE_1);
188                                 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
189                                         mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
190                                                  ME4600_DIO_CTRL_BIT_MODE_1 |
191                                                  ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
192                                 } else {
193                                         PERROR
194                                             ("Invalid port reference specified.\n");
195                                         err = ME_ERRNO_INVALID_SINGLE_CONFIG;
196                                 }
197                         } else {
198                                 PERROR("Invalid port direction specified.\n");
199                                 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
200                         }
201                 } else {
202                         PERROR("Invalid channel number.\n");
203                         err = ME_ERRNO_INVALID_CHANNEL;
204                 }
205
206                 break;
207
208         default:
209                 PERROR("Invalid flags specified.\n");
210                 err = ME_ERRNO_INVALID_FLAGS;
211         }
212
213         if (!err) {
214                 outl(mode, instance->ctrl_reg);
215                 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
216                            instance->reg_base,
217                            instance->ctrl_reg - instance->reg_base, mode);
218         }
219         spin_unlock(instance->ctrl_reg_lock);
220         spin_unlock(&instance->subdevice_lock);
221
222         ME_SUBDEVICE_EXIT;
223
224         return err;
225 }
226
227 static int me4600_do_io_single_read(me_subdevice_t *subdevice,
228                                     struct file *filep,
229                                     int channel,
230                                     int *value, int time_out, int flags)
231 {
232         me4600_do_subdevice_t *instance;
233         int err = ME_ERRNO_SUCCESS;
234         uint32_t mode;
235
236         PDEBUG("executed.\n");
237
238         instance = (me4600_do_subdevice_t *) subdevice;
239
240         ME_SUBDEVICE_ENTER;
241
242         spin_lock(&instance->subdevice_lock);
243         spin_lock(instance->ctrl_reg_lock);
244         mode =
245             inl(instance->
246                 ctrl_reg) & (ME4600_DIO_CTRL_BIT_MODE_0 |
247                              ME4600_DIO_CTRL_BIT_MODE_1);
248
249         if (mode == ME4600_DIO_CTRL_BIT_MODE_0) {
250                 switch (flags) {
251                 case ME_IO_SINGLE_TYPE_DIO_BIT:
252                         if ((channel >= 0) && (channel < 8)) {
253                                 *value =
254                                     inl(instance->port_reg) & (0x1 << channel);
255                         } else {
256                                 PERROR("Invalid bit number specified.\n");
257                                 err = ME_ERRNO_INVALID_CHANNEL;
258                         }
259                         break;
260
261                 case ME_IO_SINGLE_NO_FLAGS:
262                 case ME_IO_SINGLE_TYPE_DIO_BYTE:
263                         if (channel == 0) {
264                                 *value = inl(instance->port_reg) & 0xFF;
265                         } else {
266                                 PERROR("Invalid byte number specified.\n");
267                                 err = ME_ERRNO_INVALID_CHANNEL;
268                         }
269                         break;
270
271                 default:
272                         PERROR("Invalid flags specified.\n");
273                         err = ME_ERRNO_INVALID_FLAGS;
274                 }
275         } else {
276                 PERROR("Port not in output mode.\n");
277                 err = ME_ERRNO_PREVIOUS_CONFIG;
278         }
279         spin_unlock(instance->ctrl_reg_lock);
280         spin_unlock(&instance->subdevice_lock);
281
282         ME_SUBDEVICE_EXIT;
283
284         return err;
285 }
286
287 static int me4600_do_io_single_write(me_subdevice_t *subdevice,
288                                      struct file *filep,
289                                      int channel,
290                                      int value, int time_out, int flags)
291 {
292         me4600_do_subdevice_t *instance;
293         int err = ME_ERRNO_SUCCESS;
294         uint32_t byte;
295         uint32_t mode;
296
297         PDEBUG("executed.\n");
298
299         instance = (me4600_do_subdevice_t *) subdevice;
300
301         ME_SUBDEVICE_ENTER;
302
303         spin_lock(&instance->subdevice_lock);
304         spin_lock(instance->ctrl_reg_lock);
305         mode =
306             inl(instance->
307                 ctrl_reg) & (ME4600_DIO_CTRL_BIT_MODE_0 |
308                              ME4600_DIO_CTRL_BIT_MODE_1);
309
310         if (mode == ME4600_DIO_CTRL_BIT_MODE_0) {
311                 switch (flags) {
312
313                 case ME_IO_SINGLE_TYPE_DIO_BIT:
314                         if ((channel >= 0) && (channel < 8)) {
315                                 byte = inl(instance->port_reg) & 0xFF;
316
317                                 if (value)
318                                         byte |= 0x1 << channel;
319                                 else
320                                         byte &= ~(0x1 << channel);
321
322                                 outl(byte, instance->port_reg);
323                         } else {
324                                 PERROR("Invalid bit number specified.\n");
325                                 err = ME_ERRNO_INVALID_CHANNEL;
326                         }
327                         break;
328
329                 case ME_IO_SINGLE_NO_FLAGS:
330                 case ME_IO_SINGLE_TYPE_DIO_BYTE:
331                         if (channel == 0) {
332                                 outl(value, instance->port_reg);
333                         } else {
334                                 PERROR("Invalid byte number specified.\n");
335                                 err = ME_ERRNO_INVALID_CHANNEL;
336                         }
337                         break;
338
339                 default:
340                         PERROR("Invalid flags specified.\n");
341                         err = ME_ERRNO_INVALID_FLAGS;
342                 }
343         } else {
344                 PERROR("Port not in output mode.\n");
345                 err = ME_ERRNO_PREVIOUS_CONFIG;
346         }
347         spin_unlock(instance->ctrl_reg_lock);
348         spin_unlock(&instance->subdevice_lock);
349
350         ME_SUBDEVICE_EXIT;
351
352         return err;
353 }
354
355 static int me4600_do_query_number_channels(me_subdevice_t *subdevice,
356                                            int *number)
357 {
358         PDEBUG("executed.\n");
359         *number = 8;
360         return ME_ERRNO_SUCCESS;
361 }
362
363 static int me4600_do_query_subdevice_type(me_subdevice_t *subdevice,
364                                           int *type, int *subtype)
365 {
366         PDEBUG("executed.\n");
367         *type = ME_TYPE_DO;
368         *subtype = ME_SUBTYPE_SINGLE;
369         return ME_ERRNO_SUCCESS;
370 }
371
372 static int me4600_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
373 {
374         PDEBUG("executed.\n");
375         *caps = 0;
376         return ME_ERRNO_SUCCESS;
377 }
378
379 me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base,
380                                              spinlock_t *ctrl_reg_lock)
381 {
382         me4600_do_subdevice_t *subdevice;
383         int err;
384
385         PDEBUG("executed.\n");
386
387         /* Allocate memory for subdevice instance */
388         subdevice = kmalloc(sizeof(me4600_do_subdevice_t), GFP_KERNEL);
389
390         if (!subdevice) {
391                 PERROR("Cannot get memory for subdevice instance.\n");
392                 return NULL;
393         }
394
395         memset(subdevice, 0, sizeof(me4600_do_subdevice_t));
396
397         /* Initialize subdevice base class */
398         err = me_subdevice_init(&subdevice->base);
399
400         if (err) {
401                 PERROR("Cannot initialize subdevice base class instance.\n");
402                 kfree(subdevice);
403                 return NULL;
404         }
405         // Initialize spin locks.
406         spin_lock_init(&subdevice->subdevice_lock);
407
408         subdevice->ctrl_reg_lock = ctrl_reg_lock;
409
410         /* Save the subdevice index */
411         subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
412         subdevice->port_reg = reg_base + ME4600_DIO_PORT_0_REG;
413 #ifdef MEDEBUG_DEBUG_REG
414         subdevice->reg_base = reg_base;
415 #endif
416
417         /* Overload base class methods. */
418         subdevice->base.me_subdevice_io_reset_subdevice =
419             me4600_do_io_reset_subdevice;
420         subdevice->base.me_subdevice_io_single_config =
421             me4600_do_io_single_config;
422         subdevice->base.me_subdevice_io_single_read = me4600_do_io_single_read;
423         subdevice->base.me_subdevice_io_single_write =
424             me4600_do_io_single_write;
425         subdevice->base.me_subdevice_query_number_channels =
426             me4600_do_query_number_channels;
427         subdevice->base.me_subdevice_query_subdevice_type =
428             me4600_do_query_subdevice_type;
429         subdevice->base.me_subdevice_query_subdevice_caps =
430             me4600_do_query_subdevice_caps;
431
432         return subdevice;
433 }