Merge branch 'topic/jack' into for-linus
[sfrench/cifs-2.6.git] / drivers / staging / meilhaus / me8100_do.c
1 /**
2  * @file me8100_do.c
3  *
4  * @brief ME-8100 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 <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 "me8100_reg.h"
48 #include "me8100_do_reg.h"
49 #include "me8100_do.h"
50
51 /*
52  * Defines
53  */
54
55 /*
56  * Functions
57  */
58
59 static int me8100_do_io_reset_subdevice(struct me_subdevice *subdevice,
60                                         struct file *filep, int flags)
61 {
62         me8100_do_subdevice_t *instance;
63         uint16_t ctrl;
64
65         PDEBUG("executed.\n");
66
67         instance = (me8100_do_subdevice_t *) subdevice;
68
69         if (flags) {
70                 PERROR("Invalid flag specified.\n");
71                 return ME_ERRNO_INVALID_FLAGS;
72         }
73
74         ME_SUBDEVICE_ENTER;
75
76         spin_lock(&instance->subdevice_lock);
77         spin_lock(instance->ctrl_reg_lock);
78         ctrl = inw(instance->ctrl_reg);
79         ctrl &= ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0;
80         outw(ctrl, instance->ctrl_reg);
81         PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
82                    instance->ctrl_reg - instance->reg_base, ctrl);
83         spin_unlock(instance->ctrl_reg_lock);
84         outw(0, instance->port_reg);
85         instance->port_reg_mirror = 0;
86         PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
87                    instance->port_reg - instance->reg_base, 0);
88         spin_unlock(&instance->subdevice_lock);
89
90         ME_SUBDEVICE_EXIT;
91
92         return ME_ERRNO_SUCCESS;
93 }
94
95 static int me8100_do_io_single_config(me_subdevice_t * subdevice,
96                                       struct file *filep,
97                                       int channel,
98                                       int single_config,
99                                       int ref,
100                                       int trig_chan,
101                                       int trig_type, int trig_edge, int flags)
102 {
103         me8100_do_subdevice_t *instance;
104         int err = ME_ERRNO_SUCCESS;
105         int config;
106
107         PDEBUG("executed.\n");
108
109         instance = (me8100_do_subdevice_t *) subdevice;
110
111         ME_SUBDEVICE_ENTER;
112
113         spin_lock(&instance->subdevice_lock);
114         spin_lock(instance->ctrl_reg_lock);
115         config = inw(instance->ctrl_reg);
116         switch (flags) {
117         case ME_IO_SINGLE_CONFIG_NO_FLAGS:
118         case ME_IO_SINGLE_CONFIG_DIO_WORD:
119                 if (channel == 0) {
120                         if (single_config ==
121                             ME_SINGLE_CONFIG_DIO_HIGH_IMPEDANCE) {
122                                 config &= ~(ME8100_DIO_CTRL_BIT_ENABLE_DIO);
123                         } else if (single_config == ME_SINGLE_CONFIG_DIO_SINK) {
124                                 config |= ME8100_DIO_CTRL_BIT_ENABLE_DIO;
125                                 config &= ~ME8100_DIO_CTRL_BIT_SOURCE;
126                         } else if (single_config == ME_SINGLE_CONFIG_DIO_SOURCE) {
127                                 config |=
128                                     ME8100_DIO_CTRL_BIT_ENABLE_DIO |
129                                     ME8100_DIO_CTRL_BIT_SOURCE;
130                         } else {
131                                 PERROR
132                                     ("Invalid port configuration specified.\n");
133                                 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
134                         }
135                 } else {
136                         PERROR("Invalid word number specified.\n");
137                         err = ME_ERRNO_INVALID_CHANNEL;
138                 }
139                 break;
140
141         default:
142                 PERROR("Invalid flags specified.\n");
143                 err = ME_ERRNO_INVALID_FLAGS;
144         }
145
146         if (!err) {
147                 outw(config, instance->ctrl_reg);
148                 PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n",
149                            instance->reg_base,
150                            instance->ctrl_reg - instance->reg_base, config);
151         }
152
153         spin_unlock(instance->ctrl_reg_lock);
154         spin_unlock(&instance->subdevice_lock);
155
156         ME_SUBDEVICE_EXIT;
157
158         return err;
159 }
160
161 static int me8100_do_io_single_read(me_subdevice_t * subdevice,
162                                     struct file *filep,
163                                     int channel,
164                                     int *value, int time_out, int flags)
165 {
166         me8100_do_subdevice_t *instance;
167         int err = ME_ERRNO_SUCCESS;
168
169         PDEBUG("executed.\n");
170
171         instance = (me8100_do_subdevice_t *) subdevice;
172
173         ME_SUBDEVICE_ENTER;
174
175         spin_lock(&instance->subdevice_lock);
176         switch (flags) {
177         case ME_IO_SINGLE_TYPE_DIO_BIT:
178                 if ((channel >= 0) && (channel < 16)) {
179                         *value = instance->port_reg_mirror & (0x1 << channel);
180                 } else {
181                         PERROR("Invalid bit number specified.\n");
182                         err = ME_ERRNO_INVALID_CHANNEL;
183                 }
184                 break;
185
186         case ME_IO_SINGLE_TYPE_DIO_BYTE:
187                 if (channel == 0) {
188                         *value = instance->port_reg_mirror & 0xFF;
189                 } else if (channel == 1) {
190                         *value = (instance->port_reg_mirror >> 8) & 0xFF;
191                 } else {
192                         PERROR("Invalid byte number specified.\n");
193                         err = ME_ERRNO_INVALID_CHANNEL;
194                 }
195                 break;
196
197         case ME_IO_SINGLE_NO_FLAGS:
198         case ME_IO_SINGLE_TYPE_DIO_WORD:
199                 if (channel == 0) {
200                         *value = instance->port_reg_mirror;
201                 } else {
202                         PERROR("Invalid word number specified.\n");
203                         err = ME_ERRNO_INVALID_CHANNEL;
204                 }
205                 break;
206
207         default:
208                 PERROR("Invalid flags specified.\n");
209                 err = ME_ERRNO_INVALID_FLAGS;
210         }
211         spin_unlock(&instance->subdevice_lock);
212
213         ME_SUBDEVICE_EXIT;
214
215         return err;
216 }
217
218 static int me8100_do_io_single_write(me_subdevice_t * subdevice,
219                                      struct file *filep,
220                                      int channel,
221                                      int value, int time_out, int flags)
222 {
223         me8100_do_subdevice_t *instance;
224         int err = ME_ERRNO_SUCCESS;
225
226         PDEBUG("executed.\n");
227
228         instance = (me8100_do_subdevice_t *) subdevice;
229
230         ME_SUBDEVICE_ENTER;
231
232         spin_lock(&instance->subdevice_lock);
233         switch (flags) {
234         case ME_IO_SINGLE_TYPE_DIO_BIT:
235                 if ((channel >= 0) && (channel < 16)) {
236                         instance->port_reg_mirror =
237                             value ? (instance->
238                                      port_reg_mirror | (0x1 << channel))
239                             : (instance->port_reg_mirror & ~(0x1 << channel));
240                         outw(instance->port_reg_mirror, instance->port_reg);
241                         PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
242                                    instance->reg_base,
243                                    instance->port_reg - instance->reg_base,
244                                    instance->port_reg_mirror);
245                 } else {
246                         PERROR("Invalid bit number specified.\n");
247                         err = ME_ERRNO_INVALID_CHANNEL;
248                 }
249                 break;
250
251         case ME_IO_SINGLE_TYPE_DIO_BYTE:
252                 if (channel == 0) {
253                         instance->port_reg_mirror &= ~0xFF;
254                         instance->port_reg_mirror |= value & 0xFF;
255                         outw(instance->port_reg_mirror, instance->port_reg);
256                         PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
257                                    instance->reg_base,
258                                    instance->port_reg - instance->reg_base,
259                                    instance->port_reg_mirror);
260                 } else if (channel == 1) {
261                         instance->port_reg_mirror &= ~0xFF00;
262                         instance->port_reg_mirror |= (value << 8) & 0xFF00;
263                         outw(instance->port_reg_mirror, instance->port_reg);
264                         PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
265                                    instance->reg_base,
266                                    instance->port_reg - instance->reg_base,
267                                    instance->port_reg_mirror);
268                 } else {
269                         PERROR("Invalid byte number specified.\n");
270                         err = ME_ERRNO_INVALID_CHANNEL;
271                 }
272                 break;
273
274         case ME_IO_SINGLE_NO_FLAGS:
275         case ME_IO_SINGLE_TYPE_DIO_WORD:
276                 if (channel == 0) {
277                         instance->port_reg_mirror = value;
278                         outw(value, instance->port_reg);
279                         PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
280                                    instance->reg_base,
281                                    instance->port_reg - instance->reg_base,
282                                    value);
283                 } else {
284                         PERROR("Invalid byte number specified.\n");
285                         err = ME_ERRNO_INVALID_CHANNEL;
286                 }
287                 break;
288
289         default:
290                 PERROR("Invalid flags specified.\n");
291                 err = ME_ERRNO_INVALID_FLAGS;
292         }
293         spin_unlock(&instance->subdevice_lock);
294
295         ME_SUBDEVICE_EXIT;
296
297         return err;
298 }
299
300 static int me8100_do_query_number_channels(me_subdevice_t * subdevice,
301                                            int *number)
302 {
303         PDEBUG("executed.\n");
304         *number = 16;
305         return ME_ERRNO_SUCCESS;
306 }
307
308 static int me8100_do_query_subdevice_type(me_subdevice_t * subdevice,
309                                           int *type, int *subtype)
310 {
311         PDEBUG("executed.\n");
312         *type = ME_TYPE_DO;
313         *subtype = ME_SUBTYPE_SINGLE;
314         return ME_ERRNO_SUCCESS;
315 }
316
317 static int me8100_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
318 {
319         PDEBUG("executed.\n");
320         *caps = ME_CAPS_DIO_SINK_SOURCE;
321         return ME_ERRNO_SUCCESS;
322 }
323
324 me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base,
325                                              unsigned int do_idx,
326                                              spinlock_t * ctrl_reg_lock)
327 {
328         me8100_do_subdevice_t *subdevice;
329         int err;
330
331         PDEBUG("executed.\n");
332
333         /* Allocate memory for subdevice instance */
334         subdevice = kmalloc(sizeof(me8100_do_subdevice_t), GFP_KERNEL);
335
336         if (!subdevice) {
337                 PERROR("Cannot get memory for subdevice instance.\n");
338                 return NULL;
339         }
340
341         memset(subdevice, 0, sizeof(me8100_do_subdevice_t));
342
343         /* Initialize subdevice base class */
344         err = me_subdevice_init(&subdevice->base);
345
346         if (err) {
347                 PERROR("Cannot initialize subdevice base class instance.\n");
348                 kfree(subdevice);
349                 return NULL;
350         }
351
352         /* Initialize registers */
353         if (do_idx == 0) {
354                 subdevice->port_reg = reg_base + ME8100_DO_REG_A;
355                 subdevice->ctrl_reg = reg_base + ME8100_CTRL_REG_A;
356         } else if (do_idx == 1) {
357                 subdevice->port_reg = reg_base + ME8100_DO_REG_B;
358                 subdevice->ctrl_reg = reg_base + ME8100_CTRL_REG_B;
359         } else {
360                 PERROR("Wrong subdevice idx=%d.\n", do_idx);
361                 kfree(subdevice);
362                 return NULL;
363         }
364 #ifdef MEDEBUG_DEBUG_REG
365         subdevice->reg_base = reg_base;
366 #endif
367
368         // Initialize spin locks.
369         spin_lock_init(&subdevice->subdevice_lock);
370         subdevice->ctrl_reg_lock = ctrl_reg_lock;
371
372         /* Save the subdevice index */
373         subdevice->do_idx = do_idx;
374
375         /* Overload base class methods. */
376         subdevice->base.me_subdevice_io_reset_subdevice =
377             me8100_do_io_reset_subdevice;
378         subdevice->base.me_subdevice_io_single_config =
379             me8100_do_io_single_config;
380         subdevice->base.me_subdevice_io_single_read = me8100_do_io_single_read;
381         subdevice->base.me_subdevice_io_single_write =
382             me8100_do_io_single_write;
383         subdevice->base.me_subdevice_query_number_channels =
384             me8100_do_query_number_channels;
385         subdevice->base.me_subdevice_query_subdevice_type =
386             me8100_do_query_subdevice_type;
387         subdevice->base.me_subdevice_query_subdevice_caps =
388             me8100_do_query_subdevice_caps;
389
390         return subdevice;
391 }