Merge branch 'irq-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6] / drivers / staging / meilhaus / me4600_dio.c
1 /**
2  * @file me4600_dio.c
3  *
4  * @brief ME-4000 digital input/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 <asm/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_dio.h"
49
50 /*
51  * Defines
52  */
53
54 /*
55  * Functions
56  */
57
58 static int me4600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
59                                          struct file *filep, int flags)
60 {
61         me4600_dio_subdevice_t *instance;
62         uint32_t mode;
63
64         PDEBUG("executed.\n");
65
66         instance = (me4600_dio_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 input mode */
76         spin_lock(&instance->subdevice_lock);
77         spin_lock(instance->ctrl_reg_lock);
78         mode = inl(instance->ctrl_reg);
79         mode &=
80             ~((ME4600_DIO_CTRL_BIT_MODE_0 | ME4600_DIO_CTRL_BIT_MODE_1) <<
81               (instance->dio_idx * 2));
82         outl(mode, instance->ctrl_reg);
83         PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
84                    instance->ctrl_reg - instance->reg_base, mode);
85         spin_unlock(instance->ctrl_reg_lock);
86
87         outl(0, instance->port_reg);
88         PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
89                    instance->port_reg - instance->reg_base, 0);
90         spin_unlock(&instance->subdevice_lock);
91
92         ME_SUBDEVICE_EXIT;
93
94         return ME_ERRNO_SUCCESS;
95 }
96
97 static int me4600_dio_io_single_config(me_subdevice_t * subdevice,
98                                        struct file *filep,
99                                        int channel,
100                                        int single_config,
101                                        int ref,
102                                        int trig_chan,
103                                        int trig_type, int trig_edge, int flags)
104 {
105         me4600_dio_subdevice_t *instance;
106         int err = ME_ERRNO_SUCCESS;
107         uint32_t mode;
108         uint32_t size =
109             flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
110                      | ME_IO_SINGLE_CONFIG_DIO_WORD |
111                      ME_IO_SINGLE_CONFIG_DIO_DWORD);
112         uint32_t mask;
113
114         PDEBUG("executed.\n");
115
116         instance = (me4600_dio_subdevice_t *) subdevice;
117
118         ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
119         spin_lock(instance->ctrl_reg_lock);
120         mode = inl(instance->ctrl_reg);
121         switch (size) {
122         case ME_IO_SINGLE_CONFIG_NO_FLAGS:
123         case ME_IO_SINGLE_CONFIG_DIO_BYTE:
124                 if (channel == 0) {
125                         if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
126                                 mode &=
127                                     ~((ME4600_DIO_CTRL_BIT_MODE_0 |
128                                        ME4600_DIO_CTRL_BIT_MODE_1) <<
129                                       (instance->dio_idx * 2));
130                         } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
131                                 mode &=
132                                     ~((ME4600_DIO_CTRL_BIT_MODE_0 |
133                                        ME4600_DIO_CTRL_BIT_MODE_1) <<
134                                       (instance->dio_idx * 2));
135                                 mode |=
136                                     ME4600_DIO_CTRL_BIT_MODE_0 << (instance->
137                                                                    dio_idx * 2);
138                         } else if (single_config == ME_SINGLE_CONFIG_DIO_MUX32M) {
139                                 mask =
140                                     (ME4600_DIO_CTRL_BIT_MODE_0 |
141                                      ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
142                                                                      dio_idx *
143                                                                      2);
144                                 mask |=
145                                     ME4600_DIO_CTRL_BIT_FUNCTION_0 |
146                                     ME4600_DIO_CTRL_BIT_FUNCTION_1;
147                                 mask |=
148                                     ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
149                                     instance->dio_idx;
150                                 mode &= ~mask;
151
152                                 if (ref == ME_REF_DIO_FIFO_LOW) {
153                                         mode |=
154                                             (ME4600_DIO_CTRL_BIT_MODE_0 |
155                                              ME4600_DIO_CTRL_BIT_MODE_1) <<
156                                             (instance->dio_idx * 2);
157                                         mode |= ME4600_DIO_CTRL_BIT_FUNCTION_1;
158                                 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
159                                         mode |=
160                                             (ME4600_DIO_CTRL_BIT_MODE_0 |
161                                              ME4600_DIO_CTRL_BIT_MODE_1) <<
162                                             (instance->dio_idx * 2);
163                                         mode |= ME4600_DIO_CTRL_BIT_FUNCTION_1;
164                                         mode |=
165                                             ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
166                                             instance->dio_idx;
167                                 } else {
168                                         PERROR
169                                             ("Invalid port reference specified.\n");
170                                         err = ME_ERRNO_INVALID_SINGLE_CONFIG;
171                                 }
172                         } else if (single_config ==
173                                    ME_SINGLE_CONFIG_DIO_DEMUX32) {
174                                 mask =
175                                     (ME4600_DIO_CTRL_BIT_MODE_0 |
176                                      ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
177                                                                      dio_idx *
178                                                                      2);
179                                 mask |=
180                                     ME4600_DIO_CTRL_BIT_FUNCTION_0 |
181                                     ME4600_DIO_CTRL_BIT_FUNCTION_1;
182                                 mask |=
183                                     ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
184                                     instance->dio_idx;
185                                 mode &= ~mask;
186
187                                 if (ref == ME_REF_DIO_FIFO_LOW) {
188                                         mode |=
189                                             (ME4600_DIO_CTRL_BIT_MODE_0 |
190                                              ME4600_DIO_CTRL_BIT_MODE_1) <<
191                                             (instance->dio_idx * 2);
192                                         mode |= ME4600_DIO_CTRL_BIT_FUNCTION_0;
193                                 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
194                                         mode |=
195                                             (ME4600_DIO_CTRL_BIT_MODE_0 |
196                                              ME4600_DIO_CTRL_BIT_MODE_1) <<
197                                             (instance->dio_idx * 2);
198                                         mode |= ME4600_DIO_CTRL_BIT_FUNCTION_0;
199                                         mode |=
200                                             ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
201                                             instance->dio_idx;
202                                 } else {
203                                         PERROR
204                                             ("Invalid port reference specified.\n");
205                                         err = ME_ERRNO_INVALID_SINGLE_CONFIG;
206                                 }
207                         } else if (single_config ==
208                                    ME_SINGLE_CONFIG_DIO_BIT_PATTERN) {
209                                 mask =
210                                     (ME4600_DIO_CTRL_BIT_MODE_0 |
211                                      ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
212                                                                      dio_idx *
213                                                                      2);
214                                 mask |=
215                                     ME4600_DIO_CTRL_BIT_FUNCTION_0 |
216                                     ME4600_DIO_CTRL_BIT_FUNCTION_1;
217                                 mask |=
218                                     ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
219                                     instance->dio_idx;
220                                 mode &= ~mask;
221
222                                 if (ref == ME_REF_DIO_FIFO_LOW) {
223                                         mode |=
224                                             (ME4600_DIO_CTRL_BIT_MODE_0 |
225                                              ME4600_DIO_CTRL_BIT_MODE_1) <<
226                                             (instance->dio_idx * 2);
227                                 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
228                                         mode |=
229                                             (ME4600_DIO_CTRL_BIT_MODE_0 |
230                                              ME4600_DIO_CTRL_BIT_MODE_1) <<
231                                             (instance->dio_idx * 2);
232                                         mode |=
233                                             ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
234                                             instance->dio_idx;
235                                 } else {
236                                         PERROR
237                                             ("Invalid port reference specified.\n");
238                                         err = ME_ERRNO_INVALID_SINGLE_CONFIG;
239                                 }
240                         } else {
241                                 PERROR
242                                     ("Invalid port configuration specified.\n");
243                                 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
244                         }
245                 } else {
246                         PERROR("Invalid channel number.\n");
247                         err = ME_ERRNO_INVALID_CHANNEL;
248                 }
249
250                 break;
251
252         default:
253                 PERROR("Invalid flags.\n");
254                 err = ME_ERRNO_INVALID_FLAGS;
255         }
256
257         if (!err) {
258                 outl(mode, instance->ctrl_reg);
259                 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
260                            instance->reg_base,
261                            instance->ctrl_reg - instance->reg_base, mode);
262         }
263         spin_unlock(instance->ctrl_reg_lock);
264         spin_unlock(&instance->subdevice_lock);
265
266         ME_SUBDEVICE_EXIT;
267
268         return err;
269 }
270
271 static int me4600_dio_io_single_read(me_subdevice_t * subdevice,
272                                      struct file *filep,
273                                      int channel,
274                                      int *value, int time_out, int flags)
275 {
276         me4600_dio_subdevice_t *instance;
277         int err = ME_ERRNO_SUCCESS;
278         uint32_t mode;
279
280         PDEBUG("executed.\n");
281
282         instance = (me4600_dio_subdevice_t *) subdevice;
283
284         ME_SUBDEVICE_ENTER;
285
286         spin_lock(&instance->subdevice_lock);
287         spin_lock(instance->ctrl_reg_lock);
288         switch (flags) {
289         case ME_IO_SINGLE_TYPE_DIO_BIT:
290                 if ((channel >= 0) && (channel < 8)) {
291                         mode =
292                             inl(instance->
293                                 ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
294                                               ME4600_DIO_CTRL_BIT_MODE_1) <<
295                                              (instance->dio_idx * 2));
296                         if ((mode ==
297                              (ME4600_DIO_CTRL_BIT_MODE_0 <<
298                               (instance->dio_idx * 2))) || !mode) {
299                                 *value =
300                                     inl(instance->port_reg) & (0x1 << channel);
301                         } else {
302                                 PERROR("Port not in output or input mode.\n");
303                                 err = ME_ERRNO_PREVIOUS_CONFIG;
304                         }
305                 } else {
306                         PERROR("Invalid bit number specified.\n");
307                         err = ME_ERRNO_INVALID_CHANNEL;
308                 }
309                 break;
310
311         case ME_IO_SINGLE_NO_FLAGS:
312         case ME_IO_SINGLE_TYPE_DIO_BYTE:
313                 if (channel == 0) {
314                         mode =
315                             inl(instance->
316                                 ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
317                                               ME4600_DIO_CTRL_BIT_MODE_1) <<
318                                              (instance->dio_idx * 2));
319                         if ((mode ==
320                              (ME4600_DIO_CTRL_BIT_MODE_0 <<
321                               (instance->dio_idx * 2))) || !mode) {
322                                 *value = inl(instance->port_reg) & 0xFF;
323                         } else {
324                                 PERROR("Port not in output or input mode.\n");
325                                 err = ME_ERRNO_PREVIOUS_CONFIG;
326                         }
327                 } else {
328                         PERROR("Invalid byte number specified.\n");
329                         err = ME_ERRNO_INVALID_CHANNEL;
330                 }
331                 break;
332
333         default:
334                 PERROR("Invalid flags specified.\n");
335                 err = ME_ERRNO_INVALID_FLAGS;
336         }
337         spin_unlock(instance->ctrl_reg_lock);
338         spin_unlock(&instance->subdevice_lock);
339
340         ME_SUBDEVICE_EXIT;
341
342         return err;
343 }
344
345 static int me4600_dio_io_single_write(me_subdevice_t * subdevice,
346                                       struct file *filep,
347                                       int channel,
348                                       int value, int time_out, int flags)
349 {
350         me4600_dio_subdevice_t *instance;
351         int err = ME_ERRNO_SUCCESS;
352         uint32_t mode;
353         uint32_t byte;
354
355         PDEBUG("executed.\n");
356
357         instance = (me4600_dio_subdevice_t *) subdevice;
358
359         ME_SUBDEVICE_ENTER;
360
361         spin_lock(&instance->subdevice_lock);
362         spin_lock(instance->ctrl_reg_lock);
363         switch (flags) {
364         case ME_IO_SINGLE_TYPE_DIO_BIT:
365                 if ((channel >= 0) && (channel < 8)) {
366                         mode =
367                             inl(instance->
368                                 ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
369                                               ME4600_DIO_CTRL_BIT_MODE_1) <<
370                                              (instance->dio_idx * 2));
371
372                         if (mode ==
373                             (ME4600_DIO_CTRL_BIT_MODE_0 <<
374                              (instance->dio_idx * 2))) {
375                                 byte = inl(instance->port_reg) & 0xFF;
376
377                                 if (value)
378                                         byte |= 0x1 << channel;
379                                 else
380                                         byte &= ~(0x1 << channel);
381
382                                 outl(byte, instance->port_reg);
383                         } else {
384                                 PERROR("Port not in output or input mode.\n");
385                                 err = ME_ERRNO_PREVIOUS_CONFIG;
386                         }
387                 } else {
388                         PERROR("Invalid bit number specified.\n");
389                         err = ME_ERRNO_INVALID_CHANNEL;
390                 }
391                 break;
392
393         case ME_IO_SINGLE_NO_FLAGS:
394         case ME_IO_SINGLE_TYPE_DIO_BYTE:
395                 if (channel == 0) {
396                         mode =
397                             inl(instance->
398                                 ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
399                                               ME4600_DIO_CTRL_BIT_MODE_1) <<
400                                              (instance->dio_idx * 2));
401
402                         if (mode ==
403                             (ME4600_DIO_CTRL_BIT_MODE_0 <<
404                              (instance->dio_idx * 2))) {
405                                 outl(value, instance->port_reg);
406                         } else {
407                                 PERROR("Port not in output or input mode.\n");
408                                 err = ME_ERRNO_PREVIOUS_CONFIG;
409                         }
410                 } else {
411                         PERROR("Invalid byte number specified.\n");
412                         err = ME_ERRNO_INVALID_CHANNEL;
413                 }
414                 break;
415
416         default:
417                 PERROR("Invalid flags specified.\n");
418                 err = ME_ERRNO_INVALID_FLAGS;
419         }
420         spin_unlock(instance->ctrl_reg_lock);
421         spin_unlock(&instance->subdevice_lock);
422
423         ME_SUBDEVICE_EXIT;
424
425         return err;
426 }
427
428 static int me4600_dio_query_number_channels(me_subdevice_t * subdevice,
429                                             int *number)
430 {
431         PDEBUG("executed.\n");
432         *number = 8;
433         return ME_ERRNO_SUCCESS;
434 }
435
436 static int me4600_dio_query_subdevice_type(me_subdevice_t * subdevice,
437                                            int *type, int *subtype)
438 {
439         PDEBUG("executed.\n");
440         *type = ME_TYPE_DIO;
441         *subtype = ME_SUBTYPE_SINGLE;
442         return ME_ERRNO_SUCCESS;
443 }
444
445 static int me4600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
446                                            int *caps)
447 {
448         PDEBUG("executed.\n");
449         *caps = ME_CAPS_DIO_DIR_BYTE;
450         return ME_ERRNO_SUCCESS;
451 }
452
453 me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base,
454                                                unsigned int dio_idx,
455                                                spinlock_t * ctrl_reg_lock)
456 {
457         me4600_dio_subdevice_t *subdevice;
458         int err;
459
460         PDEBUG("executed.\n");
461
462         /* Allocate memory for subdevice instance */
463         subdevice = kmalloc(sizeof(me4600_dio_subdevice_t), GFP_KERNEL);
464
465         if (!subdevice) {
466                 PERROR("Cannot get memory for subdevice instance.\n");
467                 return NULL;
468         }
469
470         memset(subdevice, 0, sizeof(me4600_dio_subdevice_t));
471
472         /* Initialize subdevice base class */
473         err = me_subdevice_init(&subdevice->base);
474
475         if (err) {
476                 PERROR("Cannot initialize subdevice base class instance.\n");
477                 kfree(subdevice);
478                 return NULL;
479         }
480         // Initialize spin locks.
481         spin_lock_init(&subdevice->subdevice_lock);
482         subdevice->ctrl_reg_lock = ctrl_reg_lock;
483
484         /* Save digital i/o index */
485         subdevice->dio_idx = dio_idx;
486
487         /* Save the subdevice index */
488         subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
489         subdevice->port_reg = reg_base + ME4600_DIO_PORT_REG + (dio_idx * 4);
490 #ifdef MEDEBUG_DEBUG_REG
491         subdevice->reg_base = reg_base;
492 #endif
493
494         /* Overload base class methods. */
495         subdevice->base.me_subdevice_io_reset_subdevice =
496             me4600_dio_io_reset_subdevice;
497         subdevice->base.me_subdevice_io_single_config =
498             me4600_dio_io_single_config;
499         subdevice->base.me_subdevice_io_single_read = me4600_dio_io_single_read;
500         subdevice->base.me_subdevice_io_single_write =
501             me4600_dio_io_single_write;
502         subdevice->base.me_subdevice_query_number_channels =
503             me4600_dio_query_number_channels;
504         subdevice->base.me_subdevice_query_subdevice_type =
505             me4600_dio_query_subdevice_type;
506         subdevice->base.me_subdevice_query_subdevice_caps =
507             me4600_dio_query_subdevice_caps;
508
509         return subdevice;
510 }