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)
11 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
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.
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.
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.
35 #include <linux/module.h>
37 #include <linux/slab.h>
38 #include <linux/spinlock.h>
40 #include <linux/types.h>
42 #include "medefines.h"
43 #include "meinternal.h"
47 #include "me8100_reg.h"
48 #include "me8100_do_reg.h"
49 #include "me8100_do.h"
59 static int me8100_do_io_reset_subdevice(struct me_subdevice
*subdevice
,
60 struct file
*filep
, int flags
)
62 me8100_do_subdevice_t
*instance
;
65 PDEBUG("executed.\n");
67 instance
= (me8100_do_subdevice_t
*) subdevice
;
70 PERROR("Invalid flag specified.\n");
71 return ME_ERRNO_INVALID_FLAGS
;
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
);
92 return ME_ERRNO_SUCCESS
;
95 static int me8100_do_io_single_config(me_subdevice_t
* subdevice
,
101 int trig_type
, int trig_edge
, int flags
)
103 me8100_do_subdevice_t
*instance
;
104 int err
= ME_ERRNO_SUCCESS
;
107 PDEBUG("executed.\n");
109 instance
= (me8100_do_subdevice_t
*) subdevice
;
113 spin_lock(&instance
->subdevice_lock
);
114 spin_lock(instance
->ctrl_reg_lock
);
115 config
= inw(instance
->ctrl_reg
);
117 case ME_IO_SINGLE_CONFIG_NO_FLAGS
:
118 case ME_IO_SINGLE_CONFIG_DIO_WORD
:
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
) {
128 ME8100_DIO_CTRL_BIT_ENABLE_DIO
|
129 ME8100_DIO_CTRL_BIT_SOURCE
;
132 ("Invalid port configuration specified.\n");
133 err
= ME_ERRNO_INVALID_SINGLE_CONFIG
;
136 PERROR("Invalid word number specified.\n");
137 err
= ME_ERRNO_INVALID_CHANNEL
;
142 PERROR("Invalid flags specified.\n");
143 err
= ME_ERRNO_INVALID_FLAGS
;
147 outw(config
, instance
->ctrl_reg
);
148 PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n",
150 instance
->ctrl_reg
- instance
->reg_base
, config
);
153 spin_unlock(instance
->ctrl_reg_lock
);
154 spin_unlock(&instance
->subdevice_lock
);
161 static int me8100_do_io_single_read(me_subdevice_t
* subdevice
,
164 int *value
, int time_out
, int flags
)
166 me8100_do_subdevice_t
*instance
;
167 int err
= ME_ERRNO_SUCCESS
;
169 PDEBUG("executed.\n");
171 instance
= (me8100_do_subdevice_t
*) subdevice
;
175 spin_lock(&instance
->subdevice_lock
);
177 case ME_IO_SINGLE_TYPE_DIO_BIT
:
178 if ((channel
>= 0) && (channel
< 16)) {
179 *value
= instance
->port_reg_mirror
& (0x1 << channel
);
181 PERROR("Invalid bit number specified.\n");
182 err
= ME_ERRNO_INVALID_CHANNEL
;
186 case ME_IO_SINGLE_TYPE_DIO_BYTE
:
188 *value
= instance
->port_reg_mirror
& 0xFF;
189 } else if (channel
== 1) {
190 *value
= (instance
->port_reg_mirror
>> 8) & 0xFF;
192 PERROR("Invalid byte number specified.\n");
193 err
= ME_ERRNO_INVALID_CHANNEL
;
197 case ME_IO_SINGLE_NO_FLAGS
:
198 case ME_IO_SINGLE_TYPE_DIO_WORD
:
200 *value
= instance
->port_reg_mirror
;
202 PERROR("Invalid word number specified.\n");
203 err
= ME_ERRNO_INVALID_CHANNEL
;
208 PERROR("Invalid flags specified.\n");
209 err
= ME_ERRNO_INVALID_FLAGS
;
211 spin_unlock(&instance
->subdevice_lock
);
218 static int me8100_do_io_single_write(me_subdevice_t
* subdevice
,
221 int value
, int time_out
, int flags
)
223 me8100_do_subdevice_t
*instance
;
224 int err
= ME_ERRNO_SUCCESS
;
226 PDEBUG("executed.\n");
228 instance
= (me8100_do_subdevice_t
*) subdevice
;
232 spin_lock(&instance
->subdevice_lock
);
234 case ME_IO_SINGLE_TYPE_DIO_BIT
:
235 if ((channel
>= 0) && (channel
< 16)) {
236 instance
->port_reg_mirror
=
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",
243 instance
->port_reg
- instance
->reg_base
,
244 instance
->port_reg_mirror
);
246 PERROR("Invalid bit number specified.\n");
247 err
= ME_ERRNO_INVALID_CHANNEL
;
251 case ME_IO_SINGLE_TYPE_DIO_BYTE
:
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",
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",
266 instance
->port_reg
- instance
->reg_base
,
267 instance
->port_reg_mirror
);
269 PERROR("Invalid byte number specified.\n");
270 err
= ME_ERRNO_INVALID_CHANNEL
;
274 case ME_IO_SINGLE_NO_FLAGS
:
275 case ME_IO_SINGLE_TYPE_DIO_WORD
:
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",
281 instance
->port_reg
- instance
->reg_base
,
284 PERROR("Invalid byte number specified.\n");
285 err
= ME_ERRNO_INVALID_CHANNEL
;
290 PERROR("Invalid flags specified.\n");
291 err
= ME_ERRNO_INVALID_FLAGS
;
293 spin_unlock(&instance
->subdevice_lock
);
300 static int me8100_do_query_number_channels(me_subdevice_t
* subdevice
,
303 PDEBUG("executed.\n");
305 return ME_ERRNO_SUCCESS
;
308 static int me8100_do_query_subdevice_type(me_subdevice_t
* subdevice
,
309 int *type
, int *subtype
)
311 PDEBUG("executed.\n");
313 *subtype
= ME_SUBTYPE_SINGLE
;
314 return ME_ERRNO_SUCCESS
;
317 static int me8100_do_query_subdevice_caps(me_subdevice_t
* subdevice
, int *caps
)
319 PDEBUG("executed.\n");
320 *caps
= ME_CAPS_DIO_SINK_SOURCE
;
321 return ME_ERRNO_SUCCESS
;
324 me8100_do_subdevice_t
*me8100_do_constructor(uint32_t reg_base
,
326 spinlock_t
* ctrl_reg_lock
)
328 me8100_do_subdevice_t
*subdevice
;
331 PDEBUG("executed.\n");
333 /* Allocate memory for subdevice instance */
334 subdevice
= kmalloc(sizeof(me8100_do_subdevice_t
), GFP_KERNEL
);
337 PERROR("Cannot get memory for subdevice instance.\n");
341 memset(subdevice
, 0, sizeof(me8100_do_subdevice_t
));
343 /* Initialize subdevice base class */
344 err
= me_subdevice_init(&subdevice
->base
);
347 PERROR("Cannot initialize subdevice base class instance.\n");
352 /* Initialize registers */
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
;
360 PERROR("Wrong subdevice idx=%d.\n", do_idx
);
364 #ifdef MEDEBUG_DEBUG_REG
365 subdevice
->reg_base
= reg_base
;
368 // Initialize spin locks.
369 spin_lock_init(&subdevice
->subdevice_lock
);
370 subdevice
->ctrl_reg_lock
= ctrl_reg_lock
;
372 /* Save the subdevice index */
373 subdevice
->do_idx
= do_idx
;
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
;