]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/meilhaus/me8200_di.c
Merge branch 'topic/asoc' into for-linus
[mv-sheeva.git] / drivers / staging / meilhaus / me8200_di.c
1 /**
2  * @file me8200_di.c
3  *
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)
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 ///Includes
33 #include <linux/module.h>
34
35 #include <linux/slab.h>
36 #include <linux/spinlock.h>
37 #include <linux/io.h>
38 #include <linux/types.h>
39 #include <linux/interrupt.h>
40 #include <linux/version.h>
41
42 #include "medefines.h"
43 #include "meerror.h"
44
45 #include "meids.h"
46 #include "medebug.h"
47 #include "me8200_reg.h"
48 #include "me8200_di_reg.h"
49 #include "me8200_di.h"
50
51 /// Defines
52 static void me8200_di_destructor(struct me_subdevice *subdevice);
53 static int me8200_di_io_irq_start(me_subdevice_t *subdevice,
54                                   struct file *filep,
55                                   int channel,
56                                   int irq_source,
57                                   int irq_edge, int irq_arg, int flags);
58 static int me8200_di_io_irq_wait(me_subdevice_t *subdevice,
59                                  struct file *filep,
60                                  int channel,
61                                  int *irq_count,
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,
66                                       struct file *filep,
67                                       int channel,
68                                       int single_config,
69                                       int ref,
70                                       int trig_chan,
71                                       int trig_type, int trig_edge, int flags);
72 static int me8200_di_io_single_read(me_subdevice_t *subdevice,
73                                     struct file *filep,
74                                     int channel,
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,
79                                            int *number);
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,
83                                           int *caps);
84 static irqreturn_t me8200_isr(int irq, void *dev_id);
85 static irqreturn_t me8200_isr_EX(int irq, void *dev_id);
86 static void me8200_di_check_version(me8200_di_subdevice_t *instance,
87                                     unsigned long addr);
88
89 ///Functions
90 static int me8200_di_io_irq_start(me_subdevice_t *subdevice,
91                                   struct file *filep,
92                                   int channel,
93                                   int irq_source,
94                                   int irq_edge, int irq_arg, int flags)
95 {
96         me8200_di_subdevice_t *instance;
97         int err = ME_ERRNO_SUCCESS;
98         volatile uint8_t tmp;
99         unsigned long status;
100
101         PDEBUG("executed.\n");
102
103         instance = (me8200_di_subdevice_t *) subdevice;
104
105         if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
106                 if (flags &
107                     ~(ME_IO_IRQ_START_PATTERN_FILTERING |
108                       ME_IO_IRQ_START_DIO_BYTE)) {
109                         PERROR("Invalid flag specified.\n");
110                         return ME_ERRNO_INVALID_FLAGS;
111                 }
112
113                 if (irq_edge != ME_IRQ_EDGE_NOT_USED) {
114                         PERROR("Invalid irq edge specified.\n");
115                         return ME_ERRNO_INVALID_IRQ_EDGE;
116                 }
117         } else if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
118                 if (flags &
119                     ~(ME_IO_IRQ_START_EXTENDED_STATUS |
120                       ME_IO_IRQ_START_DIO_BYTE)) {
121                         PERROR("Invalid flag specified.\n");
122                         return ME_ERRNO_INVALID_FLAGS;
123                 }
124
125                 if ((irq_edge != ME_IRQ_EDGE_RISING)
126                     && (irq_edge != ME_IRQ_EDGE_FALLING)
127                     && (irq_edge != ME_IRQ_EDGE_ANY)) {
128                         PERROR("Invalid irq edge specified.\n");
129                         return ME_ERRNO_INVALID_IRQ_EDGE;
130                 }
131
132                 if (!(irq_arg & 0xFF)) {
133                         PERROR("No mask specified.\n");
134                         return ME_ERRNO_INVALID_IRQ_ARG;
135                 }
136         } else {
137                 PERROR("Invalid irq source specified.\n");
138                 return ME_ERRNO_INVALID_IRQ_SOURCE;
139         }
140
141         if (channel) {
142                 PERROR("Invalid channel specified.\n");
143                 return ME_ERRNO_INVALID_CHANNEL;
144         }
145
146         ME_SUBDEVICE_ENTER;
147
148         spin_lock_irqsave(&instance->subdevice_lock, status);
149         if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
150                 outb(irq_arg, instance->compare_reg);
151                 PDEBUG_REG("compare_reg outb(0x%lX+0x%lX)=0x%x\n",
152                            instance->reg_base,
153                            instance->compare_reg - instance->reg_base, irq_arg);
154                 outb(0xFF, instance->mask_reg);
155                 PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n",
156                            instance->reg_base,
157                            instance->mask_reg - instance->reg_base, 0xff);
158                 instance->compare_value = irq_arg;
159                 instance->filtering_flag =
160                     (flags & ME_IO_IRQ_START_PATTERN_FILTERING) ? 1 : 0;
161         }
162         if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
163                 outb(irq_arg, instance->mask_reg);
164                 PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n",
165                            instance->reg_base,
166                            instance->mask_reg - instance->reg_base, irq_arg);
167                 instance->filtering_flag = 0;
168         }
169
170         spin_lock(instance->irq_mode_lock);
171         tmp = inb(instance->irq_mode_reg);
172         tmp &=
173             ~(ME8200_IRQ_MODE_MASK <<
174               (ME8200_IRQ_MODE_DI_SHIFT * instance->di_idx));
175         if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
176                 tmp |=
177                     ME8200_IRQ_MODE_MASK_COMPARE << (ME8200_IRQ_MODE_DI_SHIFT *
178                                                      instance->di_idx);
179         }
180
181         if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
182                 tmp |=
183                     ME8200_IRQ_MODE_MASK_MASK << (ME8200_IRQ_MODE_DI_SHIFT *
184                                                   instance->di_idx);
185         }
186         outb(tmp, instance->irq_mode_reg);
187         PDEBUG_REG("irq_mode_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
188                    instance->irq_mode_reg - instance->reg_base, tmp);
189         spin_unlock(instance->irq_mode_lock);
190
191         spin_lock(instance->irq_ctrl_lock);
192         tmp = inb(instance->irq_ctrl_reg);
193         tmp |=
194             (ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
195              (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
196         tmp |=
197             ME8200_DI_IRQ_CTRL_BIT_ENABLE << (ME8200_DI_IRQ_CTRL_SHIFT *
198                                               instance->di_idx);
199
200         if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
201                 tmp &=
202                     ~(ME8200_DI_IRQ_CTRL_MASK_EDGE <<
203                       (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
204                 if (irq_edge == ME_IRQ_EDGE_RISING) {
205                         tmp |=
206                             ME8200_DI_IRQ_CTRL_MASK_EDGE_RISING <<
207                             (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx);
208                 } else if (irq_edge == ME_IRQ_EDGE_FALLING) {
209                         tmp |=
210                             ME8200_DI_IRQ_CTRL_MASK_EDGE_FALLING <<
211                             (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx);
212                 } else if (irq_edge == ME_IRQ_EDGE_ANY) {
213                         tmp |=
214                             ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY <<
215                             (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx);
216                 }
217         }
218         outb(tmp, instance->irq_ctrl_reg);
219         PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
220                    instance->irq_ctrl_reg - instance->reg_base, tmp);
221         tmp &=
222             ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
223               (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
224         outb(tmp, instance->irq_ctrl_reg);
225         PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
226                    instance->irq_ctrl_reg - instance->reg_base, tmp);
227
228         instance->line_value = inb(instance->port_reg);
229         spin_unlock(instance->irq_ctrl_lock);
230
231         instance->rised = 0;
232         instance->status_value = 0;
233         instance->status_value_edges = 0;
234         instance->status_flag = flags & ME_IO_IRQ_START_EXTENDED_STATUS;
235         spin_unlock_irqrestore(&instance->subdevice_lock, status);
236         ME_SUBDEVICE_EXIT;
237
238         return err;
239 }
240
241 static int me8200_di_io_irq_wait(me_subdevice_t *subdevice,
242                                  struct file *filep,
243                                  int channel,
244                                  int *irq_count,
245                                  int *value, int time_out, int flags)
246 {
247         me8200_di_subdevice_t *instance;
248         int err = ME_ERRNO_SUCCESS;
249         long t = 0;
250         unsigned long cpu_flags;
251         int count;
252
253         PDEBUG("executed.\n");
254         PDEVELOP("PID: %d.\n", current->pid);
255
256         instance = (me8200_di_subdevice_t *) subdevice;
257
258         if (flags &
259             ~(ME_IO_IRQ_WAIT_NORMAL_STATUS | ME_IO_IRQ_WAIT_EXTENDED_STATUS)) {
260                 PERROR("Invalid flag specified.\n");
261                 return ME_ERRNO_INVALID_FLAGS;
262         }
263
264         if (channel) {
265                 PERROR("Invalid channel specified.\n");
266                 return ME_ERRNO_INVALID_CHANNEL;
267         }
268
269         if (time_out < 0) {
270                 PERROR("Invalid time_out specified.\n");
271                 return ME_ERRNO_INVALID_TIMEOUT;
272         }
273
274         if (time_out) {
275                 t = (time_out * HZ) / 1000;
276
277                 if (t == 0)
278                         t = 1;
279         }
280
281         ME_SUBDEVICE_ENTER;
282
283         if (instance->rised <= 0) {
284                 instance->rised = 0;
285                 count = instance->count;
286
287                 if (time_out) {
288                         t = wait_event_interruptible_timeout(instance->
289                                                              wait_queue,
290                                                              ((count !=
291                                                                instance->count)
292                                                               || (instance->
293                                                                   rised < 0)),
294                                                              t);
295 //                      t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t);
296                         if (t == 0) {
297                                 PERROR("Wait on interrupt timed out.\n");
298                                 err = ME_ERRNO_TIMEOUT;
299                         }
300                 } else {
301                         wait_event_interruptible(instance->wait_queue,
302                                                  ((count != instance->count)
303                                                   || (instance->rised < 0)));
304 //                      wait_event_interruptible(instance->wait_queue, (instance->rised != 0));
305                 }
306
307                 if (instance->rised < 0) {
308                         PERROR("Wait on interrupt aborted by user.\n");
309                         err = ME_ERRNO_CANCELLED;
310                 }
311         }
312
313         if (signal_pending(current)) {
314                 PERROR("Wait on interrupt aborted by signal.\n");
315                 err = ME_ERRNO_SIGNAL;
316         }
317
318         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
319         *irq_count = instance->count;
320         if (!err) {
321                 if (flags & ME_IO_IRQ_WAIT_NORMAL_STATUS) {
322                         *value = instance->status_value;
323                 } else if (flags & ME_IO_IRQ_WAIT_EXTENDED_STATUS) {
324                         *value = instance->status_value_edges;
325                 } else {        // Use default
326                         if (!instance->status_flag) {
327                                 *value = instance->status_value;
328                         } else {
329                                 *value = instance->status_value_edges;
330                         }
331                 }
332                 instance->rised = 0;
333 /*
334                         instance->status_value = 0;
335                         instance->status_value_edges = 0;
336 */
337         } else {
338                 *value = 0;
339         }
340         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
341
342         ME_SUBDEVICE_EXIT;
343
344         return err;
345 }
346
347 static int me8200_di_io_irq_stop(me_subdevice_t *subdevice,
348                                  struct file *filep, int channel, int flags)
349 {
350         me8200_di_subdevice_t *instance;
351         uint8_t tmp;
352         unsigned long status;
353
354         PDEBUG("executed.\n");
355
356         instance = (me8200_di_subdevice_t *) subdevice;
357
358         if (flags) {
359                 PERROR("Invalid flag specified.\n");
360                 return ME_ERRNO_INVALID_FLAGS;
361         }
362
363         if (channel) {
364                 PERROR("Invalid channel specified.\n");
365                 return ME_ERRNO_INVALID_CHANNEL;
366         }
367
368         ME_SUBDEVICE_ENTER spin_lock_irqsave(&instance->subdevice_lock, status);
369         spin_lock(instance->irq_ctrl_lock);
370         tmp = inb(instance->irq_ctrl_reg);
371         tmp |=
372             (ME8200_DI_IRQ_CTRL_BIT_ENABLE <<
373              (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
374         outb(tmp, instance->irq_ctrl_reg);
375         PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
376                    instance->irq_ctrl_reg - instance->reg_base, tmp);
377         tmp &=
378             ~(ME8200_DI_IRQ_CTRL_BIT_ENABLE <<
379               (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
380         tmp |=
381             (ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
382              (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
383 //                      tmp &= ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
384         outb(tmp, instance->irq_ctrl_reg);
385         PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
386                    instance->irq_ctrl_reg - instance->reg_base, tmp);
387         spin_unlock(instance->irq_ctrl_lock);
388
389         instance->rised = -1;
390         instance->status_value = 0;
391         instance->status_value_edges = 0;
392         instance->filtering_flag = 0;
393         spin_unlock_irqrestore(&instance->subdevice_lock, status);
394         wake_up_interruptible_all(&instance->wait_queue);
395
396         ME_SUBDEVICE_EXIT;
397
398         return ME_ERRNO_SUCCESS;
399 }
400
401 static int me8200_di_io_single_config(me_subdevice_t *subdevice,
402                                       struct file *filep,
403                                       int channel,
404                                       int single_config,
405                                       int ref,
406                                       int trig_chan,
407                                       int trig_type, int trig_edge, int flags)
408 {
409         me8200_di_subdevice_t *instance;
410         int err = ME_ERRNO_SUCCESS;
411         unsigned long status;
412
413         PDEBUG("executed.\n");
414
415         instance = (me8200_di_subdevice_t *) subdevice;
416
417         ME_SUBDEVICE_ENTER;
418
419         spin_lock_irqsave(&instance->subdevice_lock, status);
420
421         switch (flags) {
422         case ME_IO_SINGLE_CONFIG_NO_FLAGS:
423         case ME_IO_SINGLE_CONFIG_DIO_BYTE:
424                 if (channel == 0) {
425                         if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
426                         } else {
427                                 PERROR("Invalid port direction specified.\n");
428                                 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
429                         }
430                 } else {
431                         PERROR("Invalid channel number.\n");
432                         err = ME_ERRNO_INVALID_CHANNEL;
433                 }
434                 break;
435
436         default:
437                 PERROR("Invalid flags specified.\n");
438                 err = ME_ERRNO_INVALID_FLAGS;
439         }
440
441         spin_unlock_irqrestore(&instance->subdevice_lock, status);
442
443         ME_SUBDEVICE_EXIT;
444
445         return err;
446 }
447
448 static int me8200_di_io_single_read(me_subdevice_t *subdevice,
449                                     struct file *filep,
450                                     int channel,
451                                     int *value, int time_out, int flags)
452 {
453         me8200_di_subdevice_t *instance;
454         int err = ME_ERRNO_SUCCESS;
455         unsigned long status;
456
457         PDEBUG("executed.\n");
458
459         instance = (me8200_di_subdevice_t *) subdevice;
460
461         ME_SUBDEVICE_ENTER;
462
463         spin_lock_irqsave(&instance->subdevice_lock, status);
464
465         switch (flags) {
466         case ME_IO_SINGLE_TYPE_DIO_BIT:
467                 if ((channel >= 0) && (channel < 8)) {
468                         *value = inb(instance->port_reg) & (0x1 << channel);
469                 } else {
470                         PERROR("Invalid bit number specified.\n");
471                         err = ME_ERRNO_INVALID_CHANNEL;
472                 }
473                 break;
474
475         case ME_IO_SINGLE_NO_FLAGS:
476         case ME_IO_SINGLE_TYPE_DIO_BYTE:
477                 if (channel == 0) {
478                         *value = inb(instance->port_reg);
479                 } else {
480                         PERROR("Invalid channel number.\n");
481                         err = ME_ERRNO_INVALID_CHANNEL;
482                 }
483                 break;
484
485         default:
486                 PERROR("Invalid flags specified.\n");
487                 err = ME_ERRNO_INVALID_FLAGS;
488         }
489
490         spin_unlock_irqrestore(&instance->subdevice_lock, status);
491
492         ME_SUBDEVICE_EXIT;
493
494         return err;
495 }
496
497 static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
498                                         struct file *filep, int flags)
499 {
500         me8200_di_subdevice_t *instance = (me8200_di_subdevice_t *) subdevice;
501
502         PDEBUG("executed.\n");
503
504         if (flags) {
505                 PERROR("Invalid flag specified.\n");
506                 return ME_ERRNO_INVALID_FLAGS;
507         }
508
509         instance->count = 0;
510         return me8200_di_io_irq_stop(subdevice, filep, 0, 0);
511 }
512
513 static int me8200_di_query_number_channels(me_subdevice_t *subdevice,
514                                            int *number)
515 {
516         PDEBUG("executed.\n");
517         *number = 8;
518         return ME_ERRNO_SUCCESS;
519 }
520
521 static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice,
522                                           int *type, int *subtype)
523 {
524         PDEBUG("executed.\n");
525         *type = ME_TYPE_DI;
526         *subtype = ME_SUBTYPE_SINGLE;
527         return ME_ERRNO_SUCCESS;
528 }
529
530 static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
531 {
532         PDEBUG("executed.\n");
533         *caps =
534             ME_CAPS_DIO_BIT_PATTERN_IRQ |
535             ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_RISING |
536             ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_FALLING |
537             ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY;
538         return ME_ERRNO_SUCCESS;
539 }
540
541 static irqreturn_t me8200_isr(int irq, void *dev_id)
542 {
543         me8200_di_subdevice_t *instance;
544         uint8_t ctrl;
545         uint8_t irq_status;
546         uint8_t line_value = 0;
547         uint8_t line_status = 0;
548         uint32_t status_val = 0;
549
550         instance = (me8200_di_subdevice_t *) dev_id;
551
552         if (irq != instance->irq) {
553                 PERROR("Incorrect interrupt num: %d.\n", irq);
554                 return IRQ_NONE;
555         }
556
557         irq_status = inb(instance->irq_status_reg);
558         if (!irq_status) {
559                 PINFO
560                     ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
561                      jiffies, __func__, instance->di_idx, irq_status);
562                 return IRQ_NONE;
563         }
564
565         PDEBUG("executed.\n");
566
567         spin_lock(&instance->subdevice_lock);
568         spin_lock(instance->irq_ctrl_lock);
569         ctrl = inb(instance->irq_ctrl_reg);
570         ctrl |=
571             ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT *
572                                              instance->di_idx);
573         outb(ctrl, instance->irq_ctrl_reg);
574         PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
575                    instance->irq_ctrl_reg - instance->reg_base, ctrl);
576         ctrl &=
577             ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
578               (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
579         outb(ctrl, instance->irq_ctrl_reg);
580         PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
581                    instance->irq_ctrl_reg - instance->reg_base, ctrl);
582
583         line_value = inb(instance->port_reg);
584         spin_unlock(instance->irq_ctrl_lock);
585
586         line_status = ((uint8_t) instance->line_value ^ line_value);
587
588         // Make extended information.
589         status_val |= (0x00FF & (~(uint8_t) instance->line_value & line_value)) << 16;  //Raise
590         status_val |= (0x00FF & ((uint8_t) instance->line_value & ~line_value));        //Fall
591
592         instance->line_value = (int)line_value;
593
594         if (instance->rised == 0) {
595                 instance->status_value = irq_status | line_status;
596                 instance->status_value_edges = status_val;
597         } else {
598                 instance->status_value |= irq_status | line_status;
599                 instance->status_value_edges |= status_val;
600         }
601
602         if (instance->filtering_flag) { // For compare mode only.
603                 if (instance->compare_value == instance->line_value) {
604                         instance->rised = 1;
605                         instance->count++;
606                 }
607         } else {
608                 instance->rised = 1;
609                 instance->count++;
610         }
611         spin_unlock(&instance->subdevice_lock);
612
613         spin_unlock(&instance->subdevice_lock);
614
615         wake_up_interruptible_all(&instance->wait_queue);
616
617         return IRQ_HANDLED;
618 }
619
620 static irqreturn_t me8200_isr_EX(int irq, void *dev_id)
621 {
622         me8200_di_subdevice_t *instance;
623         uint8_t irq_status = 0;
624         uint16_t irq_status_EX = 0;
625         uint32_t status_val = 0;
626         int i, j;
627
628         instance = (me8200_di_subdevice_t *) dev_id;
629
630         if (irq != instance->irq) {
631                 PERROR("Incorrect interrupt num: %d.\n", irq);
632                 return IRQ_NONE;
633         }
634
635         PDEBUG("executed.\n");
636
637         //Reset latches. Copy status to extended registers.
638         irq_status = inb(instance->irq_status_reg);
639         PDEBUG_REG("idx=%d irq_status_reg=0x%02X\n", instance->di_idx,
640                    irq_status);
641
642         if (!irq_status) {
643                 PINFO
644                     ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
645                      jiffies, __func__, instance->di_idx, irq_status);
646                 return IRQ_NONE;
647         }
648
649         irq_status_EX = inb(instance->irq_status_low_reg);
650         irq_status_EX |= (inb(instance->irq_status_high_reg) << 8);
651
652         PDEVELOP("EXTENDED REG: 0x%04x\n", irq_status_EX);
653         instance->line_value = inb(instance->port_reg);
654
655         // Format extended information.
656         for (i = 0, j = 0; i < 8; i++, j += 2) {
657                 status_val |= ((0x01 << j) & irq_status_EX) >> (j - i); //Fall
658                 status_val |= ((0x01 << (j + 1)) & irq_status_EX) << (15 - j + i);      //Raise
659         }
660
661         spin_lock(&instance->subdevice_lock);
662         if (instance->rised == 0) {
663                 instance->status_value = irq_status;
664                 instance->status_value_edges = status_val;
665         } else {
666                 instance->status_value |= irq_status;
667                 instance->status_value_edges |= status_val;
668         }
669
670         if (instance->filtering_flag) { // For compare mode only.
671                 if (instance->compare_value == instance->line_value) {
672                         instance->rised = 1;
673                         instance->count++;
674                 }
675         } else {
676                 instance->rised = 1;
677                 instance->count++;
678         }
679         spin_unlock(&instance->subdevice_lock);
680
681         wake_up_interruptible_all(&instance->wait_queue);
682
683         return IRQ_HANDLED;
684 }
685
686 static void me8200_di_destructor(struct me_subdevice *subdevice)
687 {
688         me8200_di_subdevice_t *instance;
689
690         PDEBUG("executed.\n");
691
692         instance = (me8200_di_subdevice_t *) subdevice;
693
694         free_irq(instance->irq, (void *)instance);
695         me_subdevice_deinit(&instance->base);
696         kfree(instance);
697 }
698
699 me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_regbase,
700                                              unsigned int di_idx,
701                                              int irq,
702                                              spinlock_t *irq_ctrl_lock,
703                                              spinlock_t *irq_mode_lock)
704 {
705         me8200_di_subdevice_t *subdevice;
706         int err;
707
708         PDEBUG("executed.\n");
709
710         /* Allocate memory for subdevice instance */
711         subdevice = kmalloc(sizeof(me8200_di_subdevice_t), GFP_KERNEL);
712
713         if (!subdevice) {
714                 PERROR("Cannot get memory for subdevice instance.\n");
715                 return NULL;
716         }
717
718         memset(subdevice, 0, sizeof(me8200_di_subdevice_t));
719
720         /* Initialize subdevice base class */
721         err = me_subdevice_init(&subdevice->base);
722
723         if (err) {
724                 PERROR("Cannot initialize subdevice base class instance.\n");
725                 kfree(subdevice);
726                 return NULL;
727         }
728         // Check firmware version.
729         me8200_di_check_version(subdevice,
730                                 me8200_regbase + ME8200_FIRMWARE_VERSION_REG);
731
732         // Initialize spin locks.
733         spin_lock_init(&subdevice->subdevice_lock);
734
735         subdevice->irq_ctrl_lock = irq_ctrl_lock;
736         subdevice->irq_mode_lock = irq_mode_lock;
737
738         /* Save the subdevice index. */
739         subdevice->di_idx = di_idx;
740
741         /* Initialize registers */
742         if (di_idx == 0) {
743                 subdevice->port_reg = me8200_regbase + ME8200_DI_PORT_0_REG;
744                 subdevice->mask_reg = me8200_regbase + ME8200_DI_MASK_0_REG;
745                 subdevice->compare_reg =
746                     me8200_regbase + ME8200_DI_COMPARE_0_REG;
747                 subdevice->irq_status_reg =
748                     me8200_regbase + ME8200_DI_CHANGE_0_REG;
749
750                 subdevice->irq_status_low_reg =
751                     me8200_regbase + ME8200_DI_EXTEND_CHANGE_0_LOW_REG;
752                 subdevice->irq_status_high_reg =
753                     me8200_regbase + ME8200_DI_EXTEND_CHANGE_0_HIGH_REG;
754         } else if (di_idx == 1) {
755                 subdevice->port_reg = me8200_regbase + ME8200_DI_PORT_1_REG;
756                 subdevice->mask_reg = me8200_regbase + ME8200_DI_MASK_1_REG;
757                 subdevice->compare_reg =
758                     me8200_regbase + ME8200_DI_COMPARE_1_REG;
759                 subdevice->irq_status_reg =
760                     me8200_regbase + ME8200_DI_CHANGE_1_REG;
761
762                 subdevice->irq_status_low_reg =
763                     me8200_regbase + ME8200_DI_EXTEND_CHANGE_1_LOW_REG;
764                 subdevice->irq_status_high_reg =
765                     me8200_regbase + ME8200_DI_EXTEND_CHANGE_1_HIGH_REG;
766         } else {
767                 PERROR("Wrong subdevice idx=%d.\n", di_idx);
768                 kfree(subdevice);
769                 return NULL;
770         }
771         subdevice->irq_ctrl_reg = me8200_regbase + ME8200_DI_IRQ_CTRL_REG;
772         subdevice->irq_mode_reg = me8200_regbase + ME8200_IRQ_MODE_REG;
773 #ifdef MEDEBUG_DEBUG_REG
774         subdevice->reg_base = me8200_regbase;
775 #endif
776
777         /* Initialize wait queue */
778         init_waitqueue_head(&subdevice->wait_queue);
779
780         /* Overload base class methods. */
781         subdevice->base.me_subdevice_io_irq_start = me8200_di_io_irq_start;
782         subdevice->base.me_subdevice_io_irq_wait = me8200_di_io_irq_wait;
783         subdevice->base.me_subdevice_io_irq_stop = me8200_di_io_irq_stop;
784         subdevice->base.me_subdevice_io_reset_subdevice =
785             me8200_di_io_reset_subdevice;
786         subdevice->base.me_subdevice_io_single_config =
787             me8200_di_io_single_config;
788         subdevice->base.me_subdevice_io_single_read = me8200_di_io_single_read;
789         subdevice->base.me_subdevice_query_number_channels =
790             me8200_di_query_number_channels;
791         subdevice->base.me_subdevice_query_subdevice_type =
792             me8200_di_query_subdevice_type;
793         subdevice->base.me_subdevice_query_subdevice_caps =
794             me8200_di_query_subdevice_caps;
795         subdevice->base.me_subdevice_destructor = me8200_di_destructor;
796
797         subdevice->rised = 0;
798         subdevice->count = 0;
799
800         /* Register interrupt service routine. */
801         subdevice->irq = irq;
802         if (subdevice->version > 0) {   // NEW
803                 err = request_irq(subdevice->irq, me8200_isr_EX,
804 #ifdef IRQF_DISABLED
805                                   IRQF_DISABLED | IRQF_SHARED,
806 #else
807                                   SA_INTERRUPT | SA_SHIRQ,
808 #endif
809                                   ME8200_NAME, (void *)subdevice);
810         } else {                //OLD
811                 err = request_irq(subdevice->irq, me8200_isr,
812 #ifdef IRQF_DISABLED
813                                   IRQF_DISABLED | IRQF_SHARED,
814 #else
815                                   SA_INTERRUPT | SA_SHIRQ,
816 #endif
817                                   ME8200_NAME, (void *)subdevice);
818         }
819
820         if (err) {
821                 PERROR("Cannot initialize subdevice base class instance.\n");
822                 kfree(subdevice);
823                 return NULL;
824         }
825         PDEBUG("Registred irq=%d.\n", subdevice->irq);
826
827         return subdevice;
828 }
829
830 static void me8200_di_check_version(me8200_di_subdevice_t *instance,
831                                     unsigned long addr)
832 {
833
834         PDEBUG("executed.\n");
835         instance->version = 0x000000FF & inb(addr);
836         PDEVELOP("me8200 firmware version: %d\n", instance->version);
837
838         /// @note Fix for wrong values in this registry.
839         if ((instance->version < 0x7) || (instance->version > 0x1F))
840                 instance->version = 0x0;
841 }