4 * @brief ME-8200 digital input 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.
33 #include <linux/module.h>
35 #include <linux/slab.h>
36 #include <linux/spinlock.h>
38 #include <linux/types.h>
39 #include <linux/interrupt.h>
41 #include "medefines.h"
46 #include "me8200_reg.h"
47 #include "me8200_di_reg.h"
48 #include "me8200_di.h"
51 static void me8200_di_destructor(struct me_subdevice
*subdevice
);
52 static int me8200_di_io_irq_start(me_subdevice_t
*subdevice
,
56 int irq_edge
, int irq_arg
, int flags
);
57 static int me8200_di_io_irq_wait(me_subdevice_t
*subdevice
,
61 int *value
, int time_out
, int flags
);
62 static int me8200_di_io_irq_stop(me_subdevice_t
*subdevice
,
63 struct file
*filep
, int channel
, int flags
);
64 static int me8200_di_io_single_config(me_subdevice_t
*subdevice
,
70 int trig_type
, int trig_edge
, int flags
);
71 static int me8200_di_io_single_read(me_subdevice_t
*subdevice
,
74 int *value
, int time_out
, int flags
);
75 static int me8200_di_io_reset_subdevice(struct me_subdevice
*subdevice
,
76 struct file
*filep
, int flags
);
77 static int me8200_di_query_number_channels(me_subdevice_t
*subdevice
,
79 static int me8200_di_query_subdevice_type(me_subdevice_t
*subdevice
,
80 int *type
, int *subtype
);
81 static int me8200_di_query_subdevice_caps(me_subdevice_t
*subdevice
,
83 static irqreturn_t
me8200_isr(int irq
, void *dev_id
);
84 static irqreturn_t
me8200_isr_EX(int irq
, void *dev_id
);
85 static void me8200_di_check_version(me8200_di_subdevice_t
*instance
,
89 static int me8200_di_io_irq_start(me_subdevice_t
*subdevice
,
93 int irq_edge
, int irq_arg
, int flags
)
95 me8200_di_subdevice_t
*instance
;
96 int err
= ME_ERRNO_SUCCESS
;
100 PDEBUG("executed.\n");
102 instance
= (me8200_di_subdevice_t
*) subdevice
;
104 if (irq_source
== ME_IRQ_SOURCE_DIO_PATTERN
) {
106 ~(ME_IO_IRQ_START_PATTERN_FILTERING
|
107 ME_IO_IRQ_START_DIO_BYTE
)) {
108 PERROR("Invalid flag specified.\n");
109 return ME_ERRNO_INVALID_FLAGS
;
112 if (irq_edge
!= ME_IRQ_EDGE_NOT_USED
) {
113 PERROR("Invalid irq edge specified.\n");
114 return ME_ERRNO_INVALID_IRQ_EDGE
;
116 } else if (irq_source
== ME_IRQ_SOURCE_DIO_MASK
) {
118 ~(ME_IO_IRQ_START_EXTENDED_STATUS
|
119 ME_IO_IRQ_START_DIO_BYTE
)) {
120 PERROR("Invalid flag specified.\n");
121 return ME_ERRNO_INVALID_FLAGS
;
124 if ((irq_edge
!= ME_IRQ_EDGE_RISING
)
125 && (irq_edge
!= ME_IRQ_EDGE_FALLING
)
126 && (irq_edge
!= ME_IRQ_EDGE_ANY
)) {
127 PERROR("Invalid irq edge specified.\n");
128 return ME_ERRNO_INVALID_IRQ_EDGE
;
131 if (!(irq_arg
& 0xFF)) {
132 PERROR("No mask specified.\n");
133 return ME_ERRNO_INVALID_IRQ_ARG
;
136 PERROR("Invalid irq source specified.\n");
137 return ME_ERRNO_INVALID_IRQ_SOURCE
;
141 PERROR("Invalid channel specified.\n");
142 return ME_ERRNO_INVALID_CHANNEL
;
147 spin_lock_irqsave(&instance
->subdevice_lock
, status
);
148 if (irq_source
== ME_IRQ_SOURCE_DIO_PATTERN
) {
149 outb(irq_arg
, instance
->compare_reg
);
150 PDEBUG_REG("compare_reg outb(0x%lX+0x%lX)=0x%x\n",
152 instance
->compare_reg
- instance
->reg_base
, irq_arg
);
153 outb(0xFF, instance
->mask_reg
);
154 PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n",
156 instance
->mask_reg
- instance
->reg_base
, 0xff);
157 instance
->compare_value
= irq_arg
;
158 instance
->filtering_flag
=
159 (flags
& ME_IO_IRQ_START_PATTERN_FILTERING
) ? 1 : 0;
161 if (irq_source
== ME_IRQ_SOURCE_DIO_MASK
) {
162 outb(irq_arg
, instance
->mask_reg
);
163 PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n",
165 instance
->mask_reg
- instance
->reg_base
, irq_arg
);
166 instance
->filtering_flag
= 0;
169 spin_lock(instance
->irq_mode_lock
);
170 tmp
= inb(instance
->irq_mode_reg
);
172 ~(ME8200_IRQ_MODE_MASK
<<
173 (ME8200_IRQ_MODE_DI_SHIFT
* instance
->di_idx
));
174 if (irq_source
== ME_IRQ_SOURCE_DIO_PATTERN
) {
176 ME8200_IRQ_MODE_MASK_COMPARE
<< (ME8200_IRQ_MODE_DI_SHIFT
*
180 if (irq_source
== ME_IRQ_SOURCE_DIO_MASK
) {
182 ME8200_IRQ_MODE_MASK_MASK
<< (ME8200_IRQ_MODE_DI_SHIFT
*
185 outb(tmp
, instance
->irq_mode_reg
);
186 PDEBUG_REG("irq_mode_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
187 instance
->irq_mode_reg
- instance
->reg_base
, tmp
);
188 spin_unlock(instance
->irq_mode_lock
);
190 spin_lock(instance
->irq_ctrl_lock
);
191 tmp
= inb(instance
->irq_ctrl_reg
);
193 (ME8200_DI_IRQ_CTRL_BIT_CLEAR
<<
194 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
196 ME8200_DI_IRQ_CTRL_BIT_ENABLE
<< (ME8200_DI_IRQ_CTRL_SHIFT
*
199 if (irq_source
== ME_IRQ_SOURCE_DIO_MASK
) {
201 ~(ME8200_DI_IRQ_CTRL_MASK_EDGE
<<
202 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
203 if (irq_edge
== ME_IRQ_EDGE_RISING
) {
205 ME8200_DI_IRQ_CTRL_MASK_EDGE_RISING
<<
206 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
);
207 } else if (irq_edge
== ME_IRQ_EDGE_FALLING
) {
209 ME8200_DI_IRQ_CTRL_MASK_EDGE_FALLING
<<
210 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
);
211 } else if (irq_edge
== ME_IRQ_EDGE_ANY
) {
213 ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY
<<
214 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
);
217 outb(tmp
, instance
->irq_ctrl_reg
);
218 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
219 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
221 ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR
<<
222 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
223 outb(tmp
, instance
->irq_ctrl_reg
);
224 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
225 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
227 instance
->line_value
= inb(instance
->port_reg
);
228 spin_unlock(instance
->irq_ctrl_lock
);
231 instance
->status_value
= 0;
232 instance
->status_value_edges
= 0;
233 instance
->status_flag
= flags
& ME_IO_IRQ_START_EXTENDED_STATUS
;
234 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
240 static int me8200_di_io_irq_wait(me_subdevice_t
*subdevice
,
244 int *value
, int time_out
, int flags
)
246 me8200_di_subdevice_t
*instance
;
247 int err
= ME_ERRNO_SUCCESS
;
249 unsigned long cpu_flags
;
252 PDEBUG("executed.\n");
253 PDEVELOP("PID: %d.\n", current
->pid
);
255 instance
= (me8200_di_subdevice_t
*) subdevice
;
258 ~(ME_IO_IRQ_WAIT_NORMAL_STATUS
| ME_IO_IRQ_WAIT_EXTENDED_STATUS
)) {
259 PERROR("Invalid flag specified.\n");
260 return ME_ERRNO_INVALID_FLAGS
;
264 PERROR("Invalid channel specified.\n");
265 return ME_ERRNO_INVALID_CHANNEL
;
269 PERROR("Invalid time_out specified.\n");
270 return ME_ERRNO_INVALID_TIMEOUT
;
274 t
= (time_out
* HZ
) / 1000;
282 if (instance
->rised
<= 0) {
284 count
= instance
->count
;
287 t
= wait_event_interruptible_timeout(instance
->
294 // t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t);
296 PERROR("Wait on interrupt timed out.\n");
297 err
= ME_ERRNO_TIMEOUT
;
300 wait_event_interruptible(instance
->wait_queue
,
301 ((count
!= instance
->count
)
302 || (instance
->rised
< 0)));
303 // wait_event_interruptible(instance->wait_queue, (instance->rised != 0));
306 if (instance
->rised
< 0) {
307 PERROR("Wait on interrupt aborted by user.\n");
308 err
= ME_ERRNO_CANCELLED
;
312 if (signal_pending(current
)) {
313 PERROR("Wait on interrupt aborted by signal.\n");
314 err
= ME_ERRNO_SIGNAL
;
317 spin_lock_irqsave(&instance
->subdevice_lock
, cpu_flags
);
318 *irq_count
= instance
->count
;
320 if (flags
& ME_IO_IRQ_WAIT_NORMAL_STATUS
) {
321 *value
= instance
->status_value
;
322 } else if (flags
& ME_IO_IRQ_WAIT_EXTENDED_STATUS
) {
323 *value
= instance
->status_value_edges
;
324 } else { // Use default
325 if (!instance
->status_flag
) {
326 *value
= instance
->status_value
;
328 *value
= instance
->status_value_edges
;
333 instance->status_value = 0;
334 instance->status_value_edges = 0;
339 spin_unlock_irqrestore(&instance
->subdevice_lock
, cpu_flags
);
346 static int me8200_di_io_irq_stop(me_subdevice_t
*subdevice
,
347 struct file
*filep
, int channel
, int flags
)
349 me8200_di_subdevice_t
*instance
;
351 unsigned long status
;
353 PDEBUG("executed.\n");
355 instance
= (me8200_di_subdevice_t
*) subdevice
;
358 PERROR("Invalid flag specified.\n");
359 return ME_ERRNO_INVALID_FLAGS
;
363 PERROR("Invalid channel specified.\n");
364 return ME_ERRNO_INVALID_CHANNEL
;
367 ME_SUBDEVICE_ENTER
spin_lock_irqsave(&instance
->subdevice_lock
, status
);
368 spin_lock(instance
->irq_ctrl_lock
);
369 tmp
= inb(instance
->irq_ctrl_reg
);
371 (ME8200_DI_IRQ_CTRL_BIT_ENABLE
<<
372 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
373 outb(tmp
, instance
->irq_ctrl_reg
);
374 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
375 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
377 ~(ME8200_DI_IRQ_CTRL_BIT_ENABLE
<<
378 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
380 (ME8200_DI_IRQ_CTRL_BIT_CLEAR
<<
381 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
382 // tmp &= ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
383 outb(tmp
, instance
->irq_ctrl_reg
);
384 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
385 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
386 spin_unlock(instance
->irq_ctrl_lock
);
388 instance
->rised
= -1;
389 instance
->status_value
= 0;
390 instance
->status_value_edges
= 0;
391 instance
->filtering_flag
= 0;
392 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
393 wake_up_interruptible_all(&instance
->wait_queue
);
397 return ME_ERRNO_SUCCESS
;
400 static int me8200_di_io_single_config(me_subdevice_t
*subdevice
,
406 int trig_type
, int trig_edge
, int flags
)
408 me8200_di_subdevice_t
*instance
;
409 int err
= ME_ERRNO_SUCCESS
;
410 unsigned long status
;
412 PDEBUG("executed.\n");
414 instance
= (me8200_di_subdevice_t
*) subdevice
;
418 spin_lock_irqsave(&instance
->subdevice_lock
, status
);
421 case ME_IO_SINGLE_CONFIG_NO_FLAGS
:
422 case ME_IO_SINGLE_CONFIG_DIO_BYTE
:
424 if (single_config
== ME_SINGLE_CONFIG_DIO_INPUT
) {
426 PERROR("Invalid port direction specified.\n");
427 err
= ME_ERRNO_INVALID_SINGLE_CONFIG
;
430 PERROR("Invalid channel number.\n");
431 err
= ME_ERRNO_INVALID_CHANNEL
;
436 PERROR("Invalid flags specified.\n");
437 err
= ME_ERRNO_INVALID_FLAGS
;
440 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
447 static int me8200_di_io_single_read(me_subdevice_t
*subdevice
,
450 int *value
, int time_out
, int flags
)
452 me8200_di_subdevice_t
*instance
;
453 int err
= ME_ERRNO_SUCCESS
;
454 unsigned long status
;
456 PDEBUG("executed.\n");
458 instance
= (me8200_di_subdevice_t
*) subdevice
;
462 spin_lock_irqsave(&instance
->subdevice_lock
, status
);
465 case ME_IO_SINGLE_TYPE_DIO_BIT
:
466 if ((channel
>= 0) && (channel
< 8)) {
467 *value
= inb(instance
->port_reg
) & (0x1 << channel
);
469 PERROR("Invalid bit number specified.\n");
470 err
= ME_ERRNO_INVALID_CHANNEL
;
474 case ME_IO_SINGLE_NO_FLAGS
:
475 case ME_IO_SINGLE_TYPE_DIO_BYTE
:
477 *value
= inb(instance
->port_reg
);
479 PERROR("Invalid channel number.\n");
480 err
= ME_ERRNO_INVALID_CHANNEL
;
485 PERROR("Invalid flags specified.\n");
486 err
= ME_ERRNO_INVALID_FLAGS
;
489 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
496 static int me8200_di_io_reset_subdevice(struct me_subdevice
*subdevice
,
497 struct file
*filep
, int flags
)
499 me8200_di_subdevice_t
*instance
= (me8200_di_subdevice_t
*) subdevice
;
501 PDEBUG("executed.\n");
504 PERROR("Invalid flag specified.\n");
505 return ME_ERRNO_INVALID_FLAGS
;
509 return me8200_di_io_irq_stop(subdevice
, filep
, 0, 0);
512 static int me8200_di_query_number_channels(me_subdevice_t
*subdevice
,
515 PDEBUG("executed.\n");
517 return ME_ERRNO_SUCCESS
;
520 static int me8200_di_query_subdevice_type(me_subdevice_t
*subdevice
,
521 int *type
, int *subtype
)
523 PDEBUG("executed.\n");
525 *subtype
= ME_SUBTYPE_SINGLE
;
526 return ME_ERRNO_SUCCESS
;
529 static int me8200_di_query_subdevice_caps(me_subdevice_t
*subdevice
, int *caps
)
531 PDEBUG("executed.\n");
533 ME_CAPS_DIO_BIT_PATTERN_IRQ
|
534 ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_RISING
|
535 ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_FALLING
|
536 ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY
;
537 return ME_ERRNO_SUCCESS
;
540 static irqreturn_t
me8200_isr(int irq
, void *dev_id
)
542 me8200_di_subdevice_t
*instance
;
545 uint8_t line_value
= 0;
546 uint8_t line_status
= 0;
547 uint32_t status_val
= 0;
549 instance
= (me8200_di_subdevice_t
*) dev_id
;
551 if (irq
!= instance
->irq
) {
552 PERROR("Incorrect interrupt num: %d.\n", irq
);
556 irq_status
= inb(instance
->irq_status_reg
);
559 ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
560 jiffies
, __func__
, instance
->di_idx
, irq_status
);
564 PDEBUG("executed.\n");
566 spin_lock(&instance
->subdevice_lock
);
567 spin_lock(instance
->irq_ctrl_lock
);
568 ctrl
= inb(instance
->irq_ctrl_reg
);
570 ME8200_DI_IRQ_CTRL_BIT_CLEAR
<< (ME8200_DI_IRQ_CTRL_SHIFT
*
572 outb(ctrl
, instance
->irq_ctrl_reg
);
573 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
574 instance
->irq_ctrl_reg
- instance
->reg_base
, ctrl
);
576 ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR
<<
577 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
578 outb(ctrl
, instance
->irq_ctrl_reg
);
579 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
580 instance
->irq_ctrl_reg
- instance
->reg_base
, ctrl
);
582 line_value
= inb(instance
->port_reg
);
583 spin_unlock(instance
->irq_ctrl_lock
);
585 line_status
= ((uint8_t) instance
->line_value
^ line_value
);
587 // Make extended information.
588 status_val
|= (0x00FF & (~(uint8_t) instance
->line_value
& line_value
)) << 16; //Raise
589 status_val
|= (0x00FF & ((uint8_t) instance
->line_value
& ~line_value
)); //Fall
591 instance
->line_value
= (int)line_value
;
593 if (instance
->rised
== 0) {
594 instance
->status_value
= irq_status
| line_status
;
595 instance
->status_value_edges
= status_val
;
597 instance
->status_value
|= irq_status
| line_status
;
598 instance
->status_value_edges
|= status_val
;
601 if (instance
->filtering_flag
) { // For compare mode only.
602 if (instance
->compare_value
== instance
->line_value
) {
610 spin_unlock(&instance
->subdevice_lock
);
612 spin_unlock(&instance
->subdevice_lock
);
614 wake_up_interruptible_all(&instance
->wait_queue
);
619 static irqreturn_t
me8200_isr_EX(int irq
, void *dev_id
)
621 me8200_di_subdevice_t
*instance
;
622 uint8_t irq_status
= 0;
623 uint16_t irq_status_EX
= 0;
624 uint32_t status_val
= 0;
627 instance
= (me8200_di_subdevice_t
*) dev_id
;
629 if (irq
!= instance
->irq
) {
630 PERROR("Incorrect interrupt num: %d.\n", irq
);
634 PDEBUG("executed.\n");
636 //Reset latches. Copy status to extended registers.
637 irq_status
= inb(instance
->irq_status_reg
);
638 PDEBUG_REG("idx=%d irq_status_reg=0x%02X\n", instance
->di_idx
,
643 ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
644 jiffies
, __func__
, instance
->di_idx
, irq_status
);
648 irq_status_EX
= inb(instance
->irq_status_low_reg
);
649 irq_status_EX
|= (inb(instance
->irq_status_high_reg
) << 8);
651 PDEVELOP("EXTENDED REG: 0x%04x\n", irq_status_EX
);
652 instance
->line_value
= inb(instance
->port_reg
);
654 // Format extended information.
655 for (i
= 0, j
= 0; i
< 8; i
++, j
+= 2) {
656 status_val
|= ((0x01 << j
) & irq_status_EX
) >> (j
- i
); //Fall
657 status_val
|= ((0x01 << (j
+ 1)) & irq_status_EX
) << (15 - j
+ i
); //Raise
660 spin_lock(&instance
->subdevice_lock
);
661 if (instance
->rised
== 0) {
662 instance
->status_value
= irq_status
;
663 instance
->status_value_edges
= status_val
;
665 instance
->status_value
|= irq_status
;
666 instance
->status_value_edges
|= status_val
;
669 if (instance
->filtering_flag
) { // For compare mode only.
670 if (instance
->compare_value
== instance
->line_value
) {
678 spin_unlock(&instance
->subdevice_lock
);
680 wake_up_interruptible_all(&instance
->wait_queue
);
685 static void me8200_di_destructor(struct me_subdevice
*subdevice
)
687 me8200_di_subdevice_t
*instance
;
689 PDEBUG("executed.\n");
691 instance
= (me8200_di_subdevice_t
*) subdevice
;
693 free_irq(instance
->irq
, (void *)instance
);
694 me_subdevice_deinit(&instance
->base
);
698 me8200_di_subdevice_t
*me8200_di_constructor(uint32_t me8200_regbase
,
701 spinlock_t
*irq_ctrl_lock
,
702 spinlock_t
*irq_mode_lock
)
704 me8200_di_subdevice_t
*subdevice
;
707 PDEBUG("executed.\n");
709 /* Allocate memory for subdevice instance */
710 subdevice
= kmalloc(sizeof(me8200_di_subdevice_t
), GFP_KERNEL
);
713 PERROR("Cannot get memory for subdevice instance.\n");
717 memset(subdevice
, 0, sizeof(me8200_di_subdevice_t
));
719 /* Initialize subdevice base class */
720 err
= me_subdevice_init(&subdevice
->base
);
723 PERROR("Cannot initialize subdevice base class instance.\n");
727 // Check firmware version.
728 me8200_di_check_version(subdevice
,
729 me8200_regbase
+ ME8200_FIRMWARE_VERSION_REG
);
731 // Initialize spin locks.
732 spin_lock_init(&subdevice
->subdevice_lock
);
734 subdevice
->irq_ctrl_lock
= irq_ctrl_lock
;
735 subdevice
->irq_mode_lock
= irq_mode_lock
;
737 /* Save the subdevice index. */
738 subdevice
->di_idx
= di_idx
;
740 /* Initialize registers */
742 subdevice
->port_reg
= me8200_regbase
+ ME8200_DI_PORT_0_REG
;
743 subdevice
->mask_reg
= me8200_regbase
+ ME8200_DI_MASK_0_REG
;
744 subdevice
->compare_reg
=
745 me8200_regbase
+ ME8200_DI_COMPARE_0_REG
;
746 subdevice
->irq_status_reg
=
747 me8200_regbase
+ ME8200_DI_CHANGE_0_REG
;
749 subdevice
->irq_status_low_reg
=
750 me8200_regbase
+ ME8200_DI_EXTEND_CHANGE_0_LOW_REG
;
751 subdevice
->irq_status_high_reg
=
752 me8200_regbase
+ ME8200_DI_EXTEND_CHANGE_0_HIGH_REG
;
753 } else if (di_idx
== 1) {
754 subdevice
->port_reg
= me8200_regbase
+ ME8200_DI_PORT_1_REG
;
755 subdevice
->mask_reg
= me8200_regbase
+ ME8200_DI_MASK_1_REG
;
756 subdevice
->compare_reg
=
757 me8200_regbase
+ ME8200_DI_COMPARE_1_REG
;
758 subdevice
->irq_status_reg
=
759 me8200_regbase
+ ME8200_DI_CHANGE_1_REG
;
761 subdevice
->irq_status_low_reg
=
762 me8200_regbase
+ ME8200_DI_EXTEND_CHANGE_1_LOW_REG
;
763 subdevice
->irq_status_high_reg
=
764 me8200_regbase
+ ME8200_DI_EXTEND_CHANGE_1_HIGH_REG
;
766 PERROR("Wrong subdevice idx=%d.\n", di_idx
);
770 subdevice
->irq_ctrl_reg
= me8200_regbase
+ ME8200_DI_IRQ_CTRL_REG
;
771 subdevice
->irq_mode_reg
= me8200_regbase
+ ME8200_IRQ_MODE_REG
;
772 #ifdef MEDEBUG_DEBUG_REG
773 subdevice
->reg_base
= me8200_regbase
;
776 /* Initialize wait queue */
777 init_waitqueue_head(&subdevice
->wait_queue
);
779 /* Overload base class methods. */
780 subdevice
->base
.me_subdevice_io_irq_start
= me8200_di_io_irq_start
;
781 subdevice
->base
.me_subdevice_io_irq_wait
= me8200_di_io_irq_wait
;
782 subdevice
->base
.me_subdevice_io_irq_stop
= me8200_di_io_irq_stop
;
783 subdevice
->base
.me_subdevice_io_reset_subdevice
=
784 me8200_di_io_reset_subdevice
;
785 subdevice
->base
.me_subdevice_io_single_config
=
786 me8200_di_io_single_config
;
787 subdevice
->base
.me_subdevice_io_single_read
= me8200_di_io_single_read
;
788 subdevice
->base
.me_subdevice_query_number_channels
=
789 me8200_di_query_number_channels
;
790 subdevice
->base
.me_subdevice_query_subdevice_type
=
791 me8200_di_query_subdevice_type
;
792 subdevice
->base
.me_subdevice_query_subdevice_caps
=
793 me8200_di_query_subdevice_caps
;
794 subdevice
->base
.me_subdevice_destructor
= me8200_di_destructor
;
796 subdevice
->rised
= 0;
797 subdevice
->count
= 0;
799 /* Register interrupt service routine. */
800 subdevice
->irq
= irq
;
801 if (subdevice
->version
> 0) { // NEW
802 err
= request_irq(subdevice
->irq
, me8200_isr_EX
,
803 IRQF_DISABLED
| IRQF_SHARED
,
804 ME8200_NAME
, (void *)subdevice
);
806 err
= request_irq(subdevice
->irq
, me8200_isr
,
807 IRQF_DISABLED
| IRQF_SHARED
,
808 ME8200_NAME
, (void *)subdevice
);
812 PERROR("Cannot initialize subdevice base class instance.\n");
816 PDEBUG("Registred irq=%d.\n", subdevice
->irq
);
821 static void me8200_di_check_version(me8200_di_subdevice_t
*instance
,
825 PDEBUG("executed.\n");
826 instance
->version
= 0x000000FF & inb(addr
);
827 PDEVELOP("me8200 firmware version: %d\n", instance
->version
);
829 /// @note Fix for wrong values in this registry.
830 if ((instance
->version
< 0x7) || (instance
->version
> 0x1F))
831 instance
->version
= 0x0;