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>
40 #include <linux/version.h>
42 #include "medefines.h"
47 #include "me8200_reg.h"
48 #include "me8200_di_reg.h"
49 #include "me8200_di.h"
52 static void me8200_di_destructor(struct me_subdevice
*subdevice
);
53 static int me8200_di_io_irq_start(me_subdevice_t
* subdevice
,
57 int irq_edge
, int irq_arg
, int flags
);
58 static int me8200_di_io_irq_wait(me_subdevice_t
* subdevice
,
62 int *value
, int time_out
, int flags
);
63 static int me8200_di_io_irq_stop(me_subdevice_t
* subdevice
,
64 struct file
*filep
, int channel
, int flags
);
65 static int me8200_di_io_single_config(me_subdevice_t
* subdevice
,
71 int trig_type
, int trig_edge
, int flags
);
72 static int me8200_di_io_single_read(me_subdevice_t
* subdevice
,
75 int *value
, int time_out
, int flags
);
76 static int me8200_di_io_reset_subdevice(struct me_subdevice
*subdevice
,
77 struct file
*filep
, int flags
);
78 static int me8200_di_query_number_channels(me_subdevice_t
* subdevice
,
80 static int me8200_di_query_subdevice_type(me_subdevice_t
* subdevice
,
81 int *type
, int *subtype
);
82 static int me8200_di_query_subdevice_caps(me_subdevice_t
* subdevice
,
84 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
85 static irqreturn_t
me8200_isr(int irq
, void *dev_id
);
87 static irqreturn_t
me8200_isr(int irq
, void *dev_id
, struct pt_regs
*regs
);
89 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
90 static irqreturn_t
me8200_isr_EX(int irq
, void *dev_id
);
92 static irqreturn_t
me8200_isr_EX(int irq
, void *dev_id
, struct pt_regs
*regs
);
94 static void me8200_di_check_version(me8200_di_subdevice_t
* instance
,
98 static int me8200_di_io_irq_start(me_subdevice_t
* subdevice
,
102 int irq_edge
, int irq_arg
, int flags
)
104 me8200_di_subdevice_t
*instance
;
105 int err
= ME_ERRNO_SUCCESS
;
106 volatile uint8_t tmp
;
107 unsigned long status
;
109 PDEBUG("executed.\n");
111 instance
= (me8200_di_subdevice_t
*) subdevice
;
113 if (irq_source
== ME_IRQ_SOURCE_DIO_PATTERN
) {
115 ~(ME_IO_IRQ_START_PATTERN_FILTERING
|
116 ME_IO_IRQ_START_DIO_BYTE
)) {
117 PERROR("Invalid flag specified.\n");
118 return ME_ERRNO_INVALID_FLAGS
;
121 if (irq_edge
!= ME_IRQ_EDGE_NOT_USED
) {
122 PERROR("Invalid irq edge specified.\n");
123 return ME_ERRNO_INVALID_IRQ_EDGE
;
125 } else if (irq_source
== ME_IRQ_SOURCE_DIO_MASK
) {
127 ~(ME_IO_IRQ_START_EXTENDED_STATUS
|
128 ME_IO_IRQ_START_DIO_BYTE
)) {
129 PERROR("Invalid flag specified.\n");
130 return ME_ERRNO_INVALID_FLAGS
;
133 if ((irq_edge
!= ME_IRQ_EDGE_RISING
)
134 && (irq_edge
!= ME_IRQ_EDGE_FALLING
)
135 && (irq_edge
!= ME_IRQ_EDGE_ANY
)) {
136 PERROR("Invalid irq edge specified.\n");
137 return ME_ERRNO_INVALID_IRQ_EDGE
;
140 if (!(irq_arg
& 0xFF)) {
141 PERROR("No mask specified.\n");
142 return ME_ERRNO_INVALID_IRQ_ARG
;
145 PERROR("Invalid irq source specified.\n");
146 return ME_ERRNO_INVALID_IRQ_SOURCE
;
150 PERROR("Invalid channel specified.\n");
151 return ME_ERRNO_INVALID_CHANNEL
;
156 spin_lock_irqsave(&instance
->subdevice_lock
, status
);
157 if (irq_source
== ME_IRQ_SOURCE_DIO_PATTERN
) {
158 outb(irq_arg
, instance
->compare_reg
);
159 PDEBUG_REG("compare_reg outb(0x%lX+0x%lX)=0x%x\n",
161 instance
->compare_reg
- instance
->reg_base
, irq_arg
);
162 outb(0xFF, instance
->mask_reg
);
163 PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n",
165 instance
->mask_reg
- instance
->reg_base
, 0xff);
166 instance
->compare_value
= irq_arg
;
167 instance
->filtering_flag
=
168 (flags
& ME_IO_IRQ_START_PATTERN_FILTERING
) ? 1 : 0;
170 if (irq_source
== ME_IRQ_SOURCE_DIO_MASK
) {
171 outb(irq_arg
, instance
->mask_reg
);
172 PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n",
174 instance
->mask_reg
- instance
->reg_base
, irq_arg
);
175 instance
->filtering_flag
= 0;
178 spin_lock(instance
->irq_mode_lock
);
179 tmp
= inb(instance
->irq_mode_reg
);
181 ~(ME8200_IRQ_MODE_MASK
<<
182 (ME8200_IRQ_MODE_DI_SHIFT
* instance
->di_idx
));
183 if (irq_source
== ME_IRQ_SOURCE_DIO_PATTERN
) {
185 ME8200_IRQ_MODE_MASK_COMPARE
<< (ME8200_IRQ_MODE_DI_SHIFT
*
189 if (irq_source
== ME_IRQ_SOURCE_DIO_MASK
) {
191 ME8200_IRQ_MODE_MASK_MASK
<< (ME8200_IRQ_MODE_DI_SHIFT
*
194 outb(tmp
, instance
->irq_mode_reg
);
195 PDEBUG_REG("irq_mode_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
196 instance
->irq_mode_reg
- instance
->reg_base
, tmp
);
197 spin_unlock(instance
->irq_mode_lock
);
199 spin_lock(instance
->irq_ctrl_lock
);
200 tmp
= inb(instance
->irq_ctrl_reg
);
202 (ME8200_DI_IRQ_CTRL_BIT_CLEAR
<<
203 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
205 ME8200_DI_IRQ_CTRL_BIT_ENABLE
<< (ME8200_DI_IRQ_CTRL_SHIFT
*
208 if (irq_source
== ME_IRQ_SOURCE_DIO_MASK
) {
210 ~(ME8200_DI_IRQ_CTRL_MASK_EDGE
<<
211 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
212 if (irq_edge
== ME_IRQ_EDGE_RISING
) {
214 ME8200_DI_IRQ_CTRL_MASK_EDGE_RISING
<<
215 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
);
216 } else if (irq_edge
== ME_IRQ_EDGE_FALLING
) {
218 ME8200_DI_IRQ_CTRL_MASK_EDGE_FALLING
<<
219 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
);
220 } else if (irq_edge
== ME_IRQ_EDGE_ANY
) {
222 ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY
<<
223 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
);
226 outb(tmp
, instance
->irq_ctrl_reg
);
227 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
228 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
230 ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR
<<
231 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
232 outb(tmp
, instance
->irq_ctrl_reg
);
233 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
234 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
236 instance
->line_value
= inb(instance
->port_reg
);
237 spin_unlock(instance
->irq_ctrl_lock
);
240 instance
->status_value
= 0;
241 instance
->status_value_edges
= 0;
242 instance
->status_flag
= flags
& ME_IO_IRQ_START_EXTENDED_STATUS
;
243 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
249 static int me8200_di_io_irq_wait(me_subdevice_t
* subdevice
,
253 int *value
, int time_out
, int flags
)
255 me8200_di_subdevice_t
*instance
;
256 int err
= ME_ERRNO_SUCCESS
;
258 unsigned long cpu_flags
;
261 PDEBUG("executed.\n");
262 PDEVELOP("PID: %d.\n", current
->pid
);
264 instance
= (me8200_di_subdevice_t
*) subdevice
;
267 ~(ME_IO_IRQ_WAIT_NORMAL_STATUS
| ME_IO_IRQ_WAIT_EXTENDED_STATUS
)) {
268 PERROR("Invalid flag specified.\n");
269 return ME_ERRNO_INVALID_FLAGS
;
273 PERROR("Invalid channel specified.\n");
274 return ME_ERRNO_INVALID_CHANNEL
;
278 PERROR("Invalid time_out specified.\n");
279 return ME_ERRNO_INVALID_TIMEOUT
;
283 t
= (time_out
* HZ
) / 1000;
291 if (instance
->rised
<= 0) {
293 count
= instance
->count
;
296 t
= wait_event_interruptible_timeout(instance
->
303 // t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t);
305 PERROR("Wait on interrupt timed out.\n");
306 err
= ME_ERRNO_TIMEOUT
;
309 wait_event_interruptible(instance
->wait_queue
,
310 ((count
!= instance
->count
)
311 || (instance
->rised
< 0)));
312 // wait_event_interruptible(instance->wait_queue, (instance->rised != 0));
315 if (instance
->rised
< 0) {
316 PERROR("Wait on interrupt aborted by user.\n");
317 err
= ME_ERRNO_CANCELLED
;
321 if (signal_pending(current
)) {
322 PERROR("Wait on interrupt aborted by signal.\n");
323 err
= ME_ERRNO_SIGNAL
;
326 spin_lock_irqsave(&instance
->subdevice_lock
, cpu_flags
);
327 *irq_count
= instance
->count
;
329 if (flags
& ME_IO_IRQ_WAIT_NORMAL_STATUS
) {
330 *value
= instance
->status_value
;
331 } else if (flags
& ME_IO_IRQ_WAIT_EXTENDED_STATUS
) {
332 *value
= instance
->status_value_edges
;
333 } else { // Use default
334 if (!instance
->status_flag
) {
335 *value
= instance
->status_value
;
337 *value
= instance
->status_value_edges
;
342 instance->status_value = 0;
343 instance->status_value_edges = 0;
348 spin_unlock_irqrestore(&instance
->subdevice_lock
, cpu_flags
);
355 static int me8200_di_io_irq_stop(me_subdevice_t
* subdevice
,
356 struct file
*filep
, int channel
, int flags
)
358 me8200_di_subdevice_t
*instance
;
360 unsigned long status
;
362 PDEBUG("executed.\n");
364 instance
= (me8200_di_subdevice_t
*) subdevice
;
367 PERROR("Invalid flag specified.\n");
368 return ME_ERRNO_INVALID_FLAGS
;
372 PERROR("Invalid channel specified.\n");
373 return ME_ERRNO_INVALID_CHANNEL
;
376 ME_SUBDEVICE_ENTER
spin_lock_irqsave(&instance
->subdevice_lock
, status
);
377 spin_lock(instance
->irq_ctrl_lock
);
378 tmp
= inb(instance
->irq_ctrl_reg
);
380 (ME8200_DI_IRQ_CTRL_BIT_ENABLE
<<
381 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
382 outb(tmp
, instance
->irq_ctrl_reg
);
383 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
384 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
386 ~(ME8200_DI_IRQ_CTRL_BIT_ENABLE
<<
387 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
389 (ME8200_DI_IRQ_CTRL_BIT_CLEAR
<<
390 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
391 // tmp &= ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
392 outb(tmp
, instance
->irq_ctrl_reg
);
393 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
394 instance
->irq_ctrl_reg
- instance
->reg_base
, tmp
);
395 spin_unlock(instance
->irq_ctrl_lock
);
397 instance
->rised
= -1;
398 instance
->status_value
= 0;
399 instance
->status_value_edges
= 0;
400 instance
->filtering_flag
= 0;
401 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
402 wake_up_interruptible_all(&instance
->wait_queue
);
406 return ME_ERRNO_SUCCESS
;
409 static int me8200_di_io_single_config(me_subdevice_t
* subdevice
,
415 int trig_type
, int trig_edge
, int flags
)
417 me8200_di_subdevice_t
*instance
;
418 int err
= ME_ERRNO_SUCCESS
;
419 unsigned long status
;
421 PDEBUG("executed.\n");
423 instance
= (me8200_di_subdevice_t
*) subdevice
;
427 spin_lock_irqsave(&instance
->subdevice_lock
, status
);
430 case ME_IO_SINGLE_CONFIG_NO_FLAGS
:
431 case ME_IO_SINGLE_CONFIG_DIO_BYTE
:
433 if (single_config
== ME_SINGLE_CONFIG_DIO_INPUT
) {
435 PERROR("Invalid port direction specified.\n");
436 err
= ME_ERRNO_INVALID_SINGLE_CONFIG
;
439 PERROR("Invalid channel number.\n");
440 err
= ME_ERRNO_INVALID_CHANNEL
;
445 PERROR("Invalid flags specified.\n");
446 err
= ME_ERRNO_INVALID_FLAGS
;
449 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
456 static int me8200_di_io_single_read(me_subdevice_t
* subdevice
,
459 int *value
, int time_out
, int flags
)
461 me8200_di_subdevice_t
*instance
;
462 int err
= ME_ERRNO_SUCCESS
;
463 unsigned long status
;
465 PDEBUG("executed.\n");
467 instance
= (me8200_di_subdevice_t
*) subdevice
;
471 spin_lock_irqsave(&instance
->subdevice_lock
, status
);
474 case ME_IO_SINGLE_TYPE_DIO_BIT
:
475 if ((channel
>= 0) && (channel
< 8)) {
476 *value
= inb(instance
->port_reg
) & (0x1 << channel
);
478 PERROR("Invalid bit number specified.\n");
479 err
= ME_ERRNO_INVALID_CHANNEL
;
483 case ME_IO_SINGLE_NO_FLAGS
:
484 case ME_IO_SINGLE_TYPE_DIO_BYTE
:
486 *value
= inb(instance
->port_reg
);
488 PERROR("Invalid channel number.\n");
489 err
= ME_ERRNO_INVALID_CHANNEL
;
494 PERROR("Invalid flags specified.\n");
495 err
= ME_ERRNO_INVALID_FLAGS
;
498 spin_unlock_irqrestore(&instance
->subdevice_lock
, status
);
505 static int me8200_di_io_reset_subdevice(struct me_subdevice
*subdevice
,
506 struct file
*filep
, int flags
)
508 me8200_di_subdevice_t
*instance
= (me8200_di_subdevice_t
*) subdevice
;
510 PDEBUG("executed.\n");
513 PERROR("Invalid flag specified.\n");
514 return ME_ERRNO_INVALID_FLAGS
;
518 return me8200_di_io_irq_stop(subdevice
, filep
, 0, 0);
521 static int me8200_di_query_number_channels(me_subdevice_t
* subdevice
,
524 PDEBUG("executed.\n");
526 return ME_ERRNO_SUCCESS
;
529 static int me8200_di_query_subdevice_type(me_subdevice_t
* subdevice
,
530 int *type
, int *subtype
)
532 PDEBUG("executed.\n");
534 *subtype
= ME_SUBTYPE_SINGLE
;
535 return ME_ERRNO_SUCCESS
;
538 static int me8200_di_query_subdevice_caps(me_subdevice_t
* subdevice
, int *caps
)
540 PDEBUG("executed.\n");
542 ME_CAPS_DIO_BIT_PATTERN_IRQ
|
543 ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_RISING
|
544 ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_FALLING
|
545 ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY
;
546 return ME_ERRNO_SUCCESS
;
549 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
550 static irqreturn_t
me8200_isr(int irq
, void *dev_id
)
552 static irqreturn_t
me8200_isr(int irq
, void *dev_id
, struct pt_regs
*regs
)
555 me8200_di_subdevice_t
*instance
;
558 uint8_t line_value
= 0;
559 uint8_t line_status
= 0;
560 uint32_t status_val
= 0;
562 instance
= (me8200_di_subdevice_t
*) dev_id
;
564 if (irq
!= instance
->irq
) {
565 PERROR("Incorrect interrupt num: %d.\n", irq
);
569 irq_status
= inb(instance
->irq_status_reg
);
572 ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
573 jiffies
, __func__
, instance
->di_idx
, irq_status
);
577 PDEBUG("executed.\n");
579 spin_lock(&instance
->subdevice_lock
);
580 spin_lock(instance
->irq_ctrl_lock
);
581 ctrl
= inb(instance
->irq_ctrl_reg
);
583 ME8200_DI_IRQ_CTRL_BIT_CLEAR
<< (ME8200_DI_IRQ_CTRL_SHIFT
*
585 outb(ctrl
, instance
->irq_ctrl_reg
);
586 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
587 instance
->irq_ctrl_reg
- instance
->reg_base
, ctrl
);
589 ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR
<<
590 (ME8200_DI_IRQ_CTRL_SHIFT
* instance
->di_idx
));
591 outb(ctrl
, instance
->irq_ctrl_reg
);
592 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance
->reg_base
,
593 instance
->irq_ctrl_reg
- instance
->reg_base
, ctrl
);
595 line_value
= inb(instance
->port_reg
);
596 spin_unlock(instance
->irq_ctrl_lock
);
598 line_status
= ((uint8_t) instance
->line_value
^ line_value
);
600 // Make extended information.
601 status_val
|= (0x00FF & (~(uint8_t) instance
->line_value
& line_value
)) << 16; //Raise
602 status_val
|= (0x00FF & ((uint8_t) instance
->line_value
& ~line_value
)); //Fall
604 instance
->line_value
= (int)line_value
;
606 if (instance
->rised
== 0) {
607 instance
->status_value
= irq_status
| line_status
;
608 instance
->status_value_edges
= status_val
;
610 instance
->status_value
|= irq_status
| line_status
;
611 instance
->status_value_edges
|= status_val
;
614 if (instance
->filtering_flag
) { // For compare mode only.
615 if (instance
->compare_value
== instance
->line_value
) {
623 spin_unlock(&instance
->subdevice_lock
);
625 spin_unlock(&instance
->subdevice_lock
);
627 wake_up_interruptible_all(&instance
->wait_queue
);
632 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
633 static irqreturn_t
me8200_isr_EX(int irq
, void *dev_id
)
635 static irqreturn_t
me8200_isr_EX(int irq
, void *dev_id
, struct pt_regs
*regs
)
638 me8200_di_subdevice_t
*instance
;
639 uint8_t irq_status
= 0;
640 uint16_t irq_status_EX
= 0;
641 uint32_t status_val
= 0;
644 instance
= (me8200_di_subdevice_t
*) dev_id
;
646 if (irq
!= instance
->irq
) {
647 PERROR("Incorrect interrupt num: %d.\n", irq
);
651 PDEBUG("executed.\n");
653 //Reset latches. Copy status to extended registers.
654 irq_status
= inb(instance
->irq_status_reg
);
655 PDEBUG_REG("idx=%d irq_status_reg=0x%02X\n", instance
->di_idx
,
660 ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
661 jiffies
, __func__
, instance
->di_idx
, irq_status
);
665 irq_status_EX
= inb(instance
->irq_status_low_reg
);
666 irq_status_EX
|= (inb(instance
->irq_status_high_reg
) << 8);
668 PDEVELOP("EXTENDED REG: 0x%04x\n", irq_status_EX
);
669 instance
->line_value
= inb(instance
->port_reg
);
671 // Format extended information.
672 for (i
= 0, j
= 0; i
< 8; i
++, j
+= 2) {
673 status_val
|= ((0x01 << j
) & irq_status_EX
) >> (j
- i
); //Fall
674 status_val
|= ((0x01 << (j
+ 1)) & irq_status_EX
) << (15 - j
+ i
); //Raise
677 spin_lock(&instance
->subdevice_lock
);
678 if (instance
->rised
== 0) {
679 instance
->status_value
= irq_status
;
680 instance
->status_value_edges
= status_val
;
682 instance
->status_value
|= irq_status
;
683 instance
->status_value_edges
|= status_val
;
686 if (instance
->filtering_flag
) { // For compare mode only.
687 if (instance
->compare_value
== instance
->line_value
) {
695 spin_unlock(&instance
->subdevice_lock
);
697 wake_up_interruptible_all(&instance
->wait_queue
);
702 static void me8200_di_destructor(struct me_subdevice
*subdevice
)
704 me8200_di_subdevice_t
*instance
;
706 PDEBUG("executed.\n");
708 instance
= (me8200_di_subdevice_t
*) subdevice
;
710 free_irq(instance
->irq
, (void *)instance
);
711 me_subdevice_deinit(&instance
->base
);
715 me8200_di_subdevice_t
*me8200_di_constructor(uint32_t me8200_regbase
,
718 spinlock_t
* irq_ctrl_lock
,
719 spinlock_t
* irq_mode_lock
)
721 me8200_di_subdevice_t
*subdevice
;
724 PDEBUG("executed.\n");
726 /* Allocate memory for subdevice instance */
727 subdevice
= kmalloc(sizeof(me8200_di_subdevice_t
), GFP_KERNEL
);
730 PERROR("Cannot get memory for subdevice instance.\n");
734 memset(subdevice
, 0, sizeof(me8200_di_subdevice_t
));
736 /* Initialize subdevice base class */
737 err
= me_subdevice_init(&subdevice
->base
);
740 PERROR("Cannot initialize subdevice base class instance.\n");
744 // Check firmware version.
745 me8200_di_check_version(subdevice
,
746 me8200_regbase
+ ME8200_FIRMWARE_VERSION_REG
);
748 // Initialize spin locks.
749 spin_lock_init(&subdevice
->subdevice_lock
);
751 subdevice
->irq_ctrl_lock
= irq_ctrl_lock
;
752 subdevice
->irq_mode_lock
= irq_mode_lock
;
754 /* Save the subdevice index. */
755 subdevice
->di_idx
= di_idx
;
757 /* Initialize registers */
759 subdevice
->port_reg
= me8200_regbase
+ ME8200_DI_PORT_0_REG
;
760 subdevice
->mask_reg
= me8200_regbase
+ ME8200_DI_MASK_0_REG
;
761 subdevice
->compare_reg
=
762 me8200_regbase
+ ME8200_DI_COMPARE_0_REG
;
763 subdevice
->irq_status_reg
=
764 me8200_regbase
+ ME8200_DI_CHANGE_0_REG
;
766 subdevice
->irq_status_low_reg
=
767 me8200_regbase
+ ME8200_DI_EXTEND_CHANGE_0_LOW_REG
;
768 subdevice
->irq_status_high_reg
=
769 me8200_regbase
+ ME8200_DI_EXTEND_CHANGE_0_HIGH_REG
;
770 } else if (di_idx
== 1) {
771 subdevice
->port_reg
= me8200_regbase
+ ME8200_DI_PORT_1_REG
;
772 subdevice
->mask_reg
= me8200_regbase
+ ME8200_DI_MASK_1_REG
;
773 subdevice
->compare_reg
=
774 me8200_regbase
+ ME8200_DI_COMPARE_1_REG
;
775 subdevice
->irq_status_reg
=
776 me8200_regbase
+ ME8200_DI_CHANGE_1_REG
;
778 subdevice
->irq_status_low_reg
=
779 me8200_regbase
+ ME8200_DI_EXTEND_CHANGE_1_LOW_REG
;
780 subdevice
->irq_status_high_reg
=
781 me8200_regbase
+ ME8200_DI_EXTEND_CHANGE_1_HIGH_REG
;
783 PERROR("Wrong subdevice idx=%d.\n", di_idx
);
787 subdevice
->irq_ctrl_reg
= me8200_regbase
+ ME8200_DI_IRQ_CTRL_REG
;
788 subdevice
->irq_mode_reg
= me8200_regbase
+ ME8200_IRQ_MODE_REG
;
789 #ifdef MEDEBUG_DEBUG_REG
790 subdevice
->reg_base
= me8200_regbase
;
793 /* Initialize wait queue */
794 init_waitqueue_head(&subdevice
->wait_queue
);
796 /* Overload base class methods. */
797 subdevice
->base
.me_subdevice_io_irq_start
= me8200_di_io_irq_start
;
798 subdevice
->base
.me_subdevice_io_irq_wait
= me8200_di_io_irq_wait
;
799 subdevice
->base
.me_subdevice_io_irq_stop
= me8200_di_io_irq_stop
;
800 subdevice
->base
.me_subdevice_io_reset_subdevice
=
801 me8200_di_io_reset_subdevice
;
802 subdevice
->base
.me_subdevice_io_single_config
=
803 me8200_di_io_single_config
;
804 subdevice
->base
.me_subdevice_io_single_read
= me8200_di_io_single_read
;
805 subdevice
->base
.me_subdevice_query_number_channels
=
806 me8200_di_query_number_channels
;
807 subdevice
->base
.me_subdevice_query_subdevice_type
=
808 me8200_di_query_subdevice_type
;
809 subdevice
->base
.me_subdevice_query_subdevice_caps
=
810 me8200_di_query_subdevice_caps
;
811 subdevice
->base
.me_subdevice_destructor
= me8200_di_destructor
;
813 subdevice
->rised
= 0;
814 subdevice
->count
= 0;
816 /* Register interrupt service routine. */
817 subdevice
->irq
= irq
;
818 if (subdevice
->version
> 0) { // NEW
819 err
= request_irq(subdevice
->irq
, me8200_isr_EX
,
821 IRQF_DISABLED
| IRQF_SHARED
,
823 SA_INTERRUPT
| SA_SHIRQ
,
825 ME8200_NAME
, (void *)subdevice
);
827 err
= request_irq(subdevice
->irq
, me8200_isr
,
829 IRQF_DISABLED
| IRQF_SHARED
,
831 SA_INTERRUPT
| SA_SHIRQ
,
833 ME8200_NAME
, (void *)subdevice
);
837 PERROR("Cannot initialize subdevice base class instance.\n");
841 PDEBUG("Registred irq=%d.\n", subdevice
->irq
);
846 static void me8200_di_check_version(me8200_di_subdevice_t
* instance
,
850 PDEBUG("executed.\n");
851 instance
->version
= 0x000000FF & inb(addr
);
852 PDEVELOP("me8200 firmware version: %d\n", instance
->version
);
854 /// @note Fix for wrong values in this registry.
855 if ((instance
->version
< 0x7) || (instance
->version
> 0x1F))
856 instance
->version
= 0x0;