4 * @brief ME-8200 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>
39 #include <linux/interrupt.h>
41 #include <linux/types.h>
42 #include <linux/version.h>
44 #include "medefines.h"
45 #include "meinternal.h"
50 #include "me8200_reg.h"
51 #include "me8200_do_reg.h"
52 #include "me8200_do.h"
62 static int me8200_do_io_irq_start(me_subdevice_t
* subdevice
,
66 int irq_edge
, int irq_arg
, int flags
)
68 me8200_do_subdevice_t
*instance
;
69 int err
= ME_ERRNO_SUCCESS
;
73 if (flags
& ~ME_IO_IRQ_START_DIO_BYTE
) {
74 PERROR("Invalid flag specified.\n");
75 return ME_ERRNO_INVALID_FLAGS
;
79 PERROR("Invalid channel specified.\n");
80 return ME_ERRNO_INVALID_CHANNEL
;
83 if (irq_source
!= ME_IRQ_SOURCE_DIO_OVER_TEMP
) {
84 PERROR("Invalid interrupt source specified.\n");
85 return ME_ERRNO_INVALID_IRQ_SOURCE
;
88 PDEBUG("executed.\n");
90 instance
= (me8200_do_subdevice_t
*) subdevice
;
94 spin_lock_irqsave(&instance
->subdevice_lock
, status
);
95 spin_lock(instance
->irq_mode_lock
);
96 tmp
= inb(instance
->irq_ctrl_reg
);
98 ME8200_IRQ_MODE_BIT_ENABLE_POWER
<< (ME8200_IRQ_MODE_POWER_SHIFT
*
100 outb(tmp
, instance
->irq_ctrl_reg
);
101 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
102 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
103 spin_unlock(instance
->irq_mode_lock
);
105 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
112 static int me8200_do_io_irq_wait(me_subdevice_t
* subdevice
,
116 int *value
, int time_out
, int flags
)
118 me8200_do_subdevice_t
*instance
;
119 int err
= ME_ERRNO_SUCCESS
;
121 unsigned long cpu_flags
;
123 PDEBUG("executed.\n");
125 instance
= (me8200_do_subdevice_t
*) subdevice
;
128 PERROR("Invalid flag specified.\n");
129 return ME_ERRNO_INVALID_FLAGS
;
133 PERROR("Invalid time_out specified.\n");
134 return ME_ERRNO_INVALID_TIMEOUT
;
138 t
= (time_out
* HZ
) / 1000;
146 if (instance
->rised
<= 0) {
150 t
= wait_event_interruptible_timeout(instance
->
157 ("Wait on external interrupt timed out.\n");
158 err
= ME_ERRNO_TIMEOUT
;
161 wait_event_interruptible(instance
->wait_queue
,
162 (instance
->rised
!= 0));
165 if (instance
->rised
< 0) {
166 PERROR("Wait on interrupt aborted by user.\n");
167 err
= ME_ERRNO_CANCELLED
;
171 if (signal_pending(current
)) {
172 PERROR("Wait on external interrupt aborted by signal.\n");
173 err
= ME_ERRNO_SIGNAL
;
176 spin_lock_irqsave(&instance
->subdevice_lock
, cpu_flags
);
178 *irq_count
= instance
->count
;
180 spin_unlock_irqrestore(&instance
->subdevice_lock
, cpu_flags
);
187 static int me8200_do_io_irq_stop(me_subdevice_t
* subdevice
,
188 struct file
*filep
, int channel
, int flags
)
190 me8200_do_subdevice_t
*instance
;
192 unsigned long cpu_flags
;
194 PDEBUG("executed.\n");
196 instance
= (me8200_do_subdevice_t
*) subdevice
;
199 PERROR("Invalid flag specified.\n");
200 return ME_ERRNO_INVALID_FLAGS
;
205 spin_lock_irqsave(&instance
->subdevice_lock
, cpu_flags
);
206 spin_lock(instance
->irq_mode_lock
);
207 tmp
= inb(instance
->irq_ctrl_reg
);
209 ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER
<<
210 (ME8200_IRQ_MODE_POWER_SHIFT
* instance
->do_idx
));
211 outb(tmp
, instance
->irq_ctrl_reg
);
212 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
213 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
214 spin_unlock(instance
->irq_mode_lock
);
215 instance
->rised
= -1;
216 spin_unlock_irqrestore(&instance
->subdevice_lock
, cpu_flags
);
217 wake_up_interruptible_all(&instance
->wait_queue
);
221 return ME_ERRNO_SUCCESS
;
224 static int me8200_do_io_reset_subdevice(struct me_subdevice
*subdevice
,
225 struct file
*filep
, int flags
)
227 me8200_do_subdevice_t
*instance
;
228 unsigned long cpu_flags
;
231 PDEBUG("executed.\n");
233 instance
= (me8200_do_subdevice_t
*) subdevice
;
236 PERROR("Invalid flag specified.\n");
237 return ME_ERRNO_INVALID_FLAGS
;
242 spin_lock_irqsave(&instance
->subdevice_lock
, cpu_flags
);
243 outb(0x00, instance
->port_reg
);
244 PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
245 instance
->port_reg
- instance
->reg_base
, 0x00);
246 spin_lock(instance
->irq_mode_lock
);
247 tmp
= inb(instance
->irq_ctrl_reg
);
249 ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER
<<
250 (ME8200_IRQ_MODE_POWER_SHIFT
* instance
->do_idx
));
251 outb(tmp
, instance
->irq_ctrl_reg
);
252 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
253 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
254 spin_unlock(instance
->irq_mode_lock
);
255 instance
->rised
= -1;
257 spin_unlock_irqrestore(&instance
->subdevice_lock
, cpu_flags
);
258 wake_up_interruptible_all(&instance
->wait_queue
);
262 return ME_ERRNO_SUCCESS
;
265 static int me8200_do_io_single_config(me_subdevice_t
* subdevice
,
271 int trig_type
, int trig_edge
, int flags
)
273 me8200_do_subdevice_t
*instance
;
274 int err
= ME_ERRNO_SUCCESS
;
275 unsigned long status
;
277 PDEBUG("executed.\n");
279 instance
= (me8200_do_subdevice_t
*) subdevice
;
283 spin_lock_irqsave(&instance
->subdevice_lock
, status
);
285 case ME_IO_SINGLE_CONFIG_NO_FLAGS
:
286 case ME_IO_SINGLE_CONFIG_DIO_BYTE
:
288 if (single_config
== ME_SINGLE_CONFIG_DIO_OUTPUT
) {
290 PERROR("Invalid byte direction specified.\n");
291 err
= ME_ERRNO_INVALID_SINGLE_CONFIG
;
294 PERROR("Invalid byte specified.\n");
295 err
= ME_ERRNO_INVALID_CHANNEL
;
300 PERROR("Invalid flags specified.\n");
301 err
= ME_ERRNO_INVALID_FLAGS
;
303 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
310 static int me8200_do_io_single_read(me_subdevice_t
* subdevice
,
313 int *value
, int time_out
, int flags
)
315 me8200_do_subdevice_t
*instance
;
316 int err
= ME_ERRNO_SUCCESS
;
317 unsigned long status
;
319 PDEBUG("executed.\n");
321 instance
= (me8200_do_subdevice_t
*) subdevice
;
325 spin_lock_irqsave(&instance
->subdevice_lock
, status
);
327 case ME_IO_SINGLE_TYPE_DIO_BIT
:
328 if ((channel
>= 0) && (channel
< 8)) {
329 *value
= inb(instance
->port_reg
) & (0x1 << channel
);
331 PERROR("Invalid bit number specified.\n");
332 err
= ME_ERRNO_INVALID_CHANNEL
;
336 case ME_IO_SINGLE_NO_FLAGS
:
337 case ME_IO_SINGLE_TYPE_DIO_BYTE
:
339 *value
= inb(instance
->port_reg
);
341 PERROR("Invalid byte number specified.\n");
342 err
= ME_ERRNO_INVALID_CHANNEL
;
347 PERROR("Invalid flags specified.\n");
348 err
= ME_ERRNO_INVALID_FLAGS
;
350 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
357 static int me8200_do_io_single_write(me_subdevice_t
* subdevice
,
360 int value
, int time_out
, int flags
)
362 me8200_do_subdevice_t
*instance
;
363 int err
= ME_ERRNO_SUCCESS
;
365 unsigned long status
;
367 PDEBUG("executed.\n");
369 instance
= (me8200_do_subdevice_t
*) subdevice
;
373 spin_lock_irqsave(&instance
->subdevice_lock
, status
);
375 case ME_IO_SINGLE_TYPE_DIO_BIT
:
376 if ((channel
>= 0) && (channel
< 8)) {
377 state
= inb(instance
->port_reg
);
379 value
? (state
| (0x1 << channel
)) : (state
&
382 outb(state
, instance
->port_reg
);
383 PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n",
385 instance
->port_reg
- instance
->reg_base
,
388 PERROR("Invalid bit number specified.\n");
389 err
= ME_ERRNO_INVALID_CHANNEL
;
393 case ME_IO_SINGLE_NO_FLAGS
:
394 case ME_IO_SINGLE_TYPE_DIO_BYTE
:
396 outb(value
, instance
->port_reg
);
397 PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n",
399 instance
->port_reg
- instance
->reg_base
,
402 PERROR("Invalid byte number specified.\n");
403 err
= ME_ERRNO_INVALID_CHANNEL
;
408 PERROR("Invalid flags specified.\n");
409 err
= ME_ERRNO_INVALID_FLAGS
;
411 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
418 static int me8200_do_query_number_channels(me_subdevice_t
* subdevice
,
421 PDEBUG("executed.\n");
423 return ME_ERRNO_SUCCESS
;
426 static int me8200_do_query_subdevice_type(me_subdevice_t
* subdevice
,
427 int *type
, int *subtype
)
429 PDEBUG("executed.\n");
431 *subtype
= ME_SUBTYPE_SINGLE
;
432 return ME_ERRNO_SUCCESS
;
435 static int me8200_do_query_subdevice_caps(me_subdevice_t
* subdevice
, int *caps
)
437 PDEBUG("executed.\n");
438 *caps
= ME_CAPS_DIO_OVER_TEMP_IRQ
;
439 return ME_ERRNO_SUCCESS
;
442 static void me8200_do_destructor(struct me_subdevice
*subdevice
)
444 me8200_do_subdevice_t
*instance
;
446 PDEBUG("executed.\n");
448 instance
= (me8200_do_subdevice_t
*) subdevice
;
450 free_irq(instance
->irq
, (void *)instance
);
451 me_subdevice_deinit(&instance
->base
);
455 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
456 static irqreturn_t
me8200_do_isr(int irq
, void *dev_id
)
458 static irqreturn_t
me8200_do_isr(int irq
, void *dev_id
, struct pt_regs
*regs
)
461 me8200_do_subdevice_t
*instance
;
465 instance
= (me8200_do_subdevice_t
*) dev_id
;
467 if (irq
!= instance
->irq
) {
468 PERROR("Incorrect interrupt num: %d.\n", irq
);
472 irq_status
= inb(instance
->irq_status_reg
);
475 (ME8200_DO_IRQ_STATUS_BIT_ACTIVE
<< instance
->do_idx
))) {
477 ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
478 jiffies
, __FUNCTION__
, instance
->do_idx
, irq_status
);
482 PDEBUG("executed.\n");
484 spin_lock(&instance
->subdevice_lock
);
488 spin_lock(instance
->irq_mode_lock
);
489 ctrl
= inw(instance
->irq_ctrl_reg
);
490 ctrl
|= ME8200_IRQ_MODE_BIT_CLEAR_POWER
<< instance
->do_idx
;
491 outw(ctrl
, instance
->irq_ctrl_reg
);
492 PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
493 instance
->irq_ctrl_reg
- instance
->reg_base
, ctrl
);
494 ctrl
&= ~(ME8200_IRQ_MODE_BIT_CLEAR_POWER
<< instance
->do_idx
);
495 outw(ctrl
, instance
->irq_ctrl_reg
);
496 PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
497 instance
->irq_ctrl_reg
- instance
->reg_base
, ctrl
);
498 spin_unlock(instance
->irq_mode_lock
);
499 spin_unlock(&instance
->subdevice_lock
);
500 wake_up_interruptible_all(&instance
->wait_queue
);
505 me8200_do_subdevice_t
*me8200_do_constructor(uint32_t reg_base
,
508 spinlock_t
* irq_mode_lock
)
510 me8200_do_subdevice_t
*subdevice
;
513 PDEBUG("executed.\n");
515 /* Allocate memory for subdevice instance */
516 subdevice
= kmalloc(sizeof(me8200_do_subdevice_t
), GFP_KERNEL
);
519 PERROR("Cannot get memory for subdevice instance.\n");
523 memset(subdevice
, 0, sizeof(me8200_do_subdevice_t
));
525 /* Initialize subdevice base class */
526 err
= me_subdevice_init(&subdevice
->base
);
529 PERROR("Cannot initialize subdevice base class instance.\n");
533 // Initialize spin locks.
534 spin_lock_init(&subdevice
->subdevice_lock
);
536 subdevice
->irq_mode_lock
= irq_mode_lock
;
538 /* Save the index of the digital output */
539 subdevice
->do_idx
= do_idx
;
540 subdevice
->irq
= irq
;
542 /* Initialize the registers */
544 subdevice
->port_reg
= reg_base
+ ME8200_DO_PORT_0_REG
;
545 } else if (do_idx
== 1) {
546 subdevice
->port_reg
= reg_base
+ ME8200_DO_PORT_1_REG
;
548 PERROR("Wrong subdevice idx=%d.\n", do_idx
);
552 subdevice
->irq_ctrl_reg
= reg_base
+ ME8200_IRQ_MODE_REG
;
553 subdevice
->irq_status_reg
= reg_base
+ ME8200_DO_IRQ_STATUS_REG
;
554 #ifdef MEDEBUG_DEBUG_REG
555 subdevice
->reg_base
= reg_base
;
558 /* Initialize the wait queue */
559 init_waitqueue_head(&subdevice
->wait_queue
);
561 /* Request the interrupt line */
562 err
= request_irq(irq
, me8200_do_isr
,
564 IRQF_DISABLED
| IRQF_SHARED
,
566 SA_INTERRUPT
| SA_SHIRQ
,
568 ME8200_NAME
, (void *)subdevice
);
571 PERROR("Cannot get interrupt line.\n");
575 PINFO("Registered irq=%d.\n", irq
);
577 /* Overload base class methods. */
578 subdevice
->base
.me_subdevice_io_irq_start
= me8200_do_io_irq_start
;
579 subdevice
->base
.me_subdevice_io_irq_wait
= me8200_do_io_irq_wait
;
580 subdevice
->base
.me_subdevice_io_irq_stop
= me8200_do_io_irq_stop
;
581 subdevice
->base
.me_subdevice_io_reset_subdevice
=
582 me8200_do_io_reset_subdevice
;
583 subdevice
->base
.me_subdevice_io_single_config
=
584 me8200_do_io_single_config
;
585 subdevice
->base
.me_subdevice_io_single_read
= me8200_do_io_single_read
;
586 subdevice
->base
.me_subdevice_io_single_write
=
587 me8200_do_io_single_write
;
588 subdevice
->base
.me_subdevice_query_number_channels
=
589 me8200_do_query_number_channels
;
590 subdevice
->base
.me_subdevice_query_subdevice_type
=
591 me8200_do_query_subdevice_type
;
592 subdevice
->base
.me_subdevice_query_subdevice_caps
=
593 me8200_do_query_subdevice_caps
;
594 subdevice
->base
.me_subdevice_destructor
= me8200_do_destructor
;
596 subdevice
->rised
= 0;
597 subdevice
->count
= 0;