Merge branch 'x86/uaccess' into core/percpu
[linux-2.6] / drivers / staging / meilhaus / me8100_di.c
1 /**
2  * @file me8100_di.c
3  *
4  * @brief ME-8100 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 /*
33  * Includes
34  */
35 #include <linux/module.h>
36
37 #include <linux/slab.h>
38 #include <linux/spinlock.h>
39 #include <asm/io.h>
40 #include <linux/types.h>
41 #include <linux/interrupt.h>
42 #include <linux/version.h>
43
44 #include "medefines.h"
45 #include "meerror.h"
46
47 #include "meids.h"
48 #include "medebug.h"
49 #include "meplx_reg.h"
50 #include "me8100_reg.h"
51 #include "me8100_di_reg.h"
52 #include "me8100_di.h"
53
54 /*
55  * Defines
56  */
57
58 /*
59  * Functions
60  */
61
62 static int me8100_di_io_reset_subdevice(struct me_subdevice *subdevice,
63                                         struct file *filep, int flags)
64 {
65         me8100_di_subdevice_t *instance;
66         unsigned short ctrl;
67         unsigned long cpu_flags;
68
69         PDEBUG("executed.\n");
70
71         instance = (me8100_di_subdevice_t *) subdevice;
72
73         if (flags) {
74                 PERROR("Invalid flag specified.\n");
75                 return ME_ERRNO_INVALID_FLAGS;
76         }
77
78         ME_SUBDEVICE_ENTER;
79
80         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
81         spin_lock(instance->ctrl_reg_lock);
82         ctrl = inw(instance->ctrl_reg);
83         ctrl &= ~(ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0);
84         outw(ctrl, instance->ctrl_reg);
85         PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
86                    instance->ctrl_reg - instance->reg_base, ctrl);
87         spin_unlock(instance->ctrl_reg_lock);
88
89         outw(0, instance->mask_reg);
90         PDEBUG_REG("mask_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
91                    instance->mask_reg - instance->reg_base, 0);
92         outw(0, instance->pattern_reg);
93         PDEBUG_REG("pattern_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
94                    instance->pattern_reg - instance->reg_base, 0);
95         instance->rised = -1;
96         instance->irq_count = 0;
97         instance->filtering_flag = 0;
98         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
99
100         outl(PLX_INTCSR_LOCAL_INT1_EN |
101              PLX_INTCSR_LOCAL_INT1_POL |
102              PLX_INTCSR_LOCAL_INT2_EN |
103              PLX_INTCSR_LOCAL_INT2_POL |
104              PLX_INTCSR_PCI_INT_EN, instance->irq_status_reg);
105         PDEBUG_REG("plx:irq_status_reg outl(0x%lX)=0x%x\n",
106                    instance->irq_status_reg,
107                    PLX_INTCSR_LOCAL_INT1_EN | PLX_INTCSR_LOCAL_INT1_POL |
108                    PLX_INTCSR_LOCAL_INT2_EN | PLX_INTCSR_LOCAL_INT2_POL |
109                    PLX_INTCSR_PCI_INT_EN);
110
111         wake_up_interruptible_all(&instance->wait_queue);
112         ME_SUBDEVICE_EXIT;
113
114         return ME_ERRNO_SUCCESS;
115 }
116
117 static int me8100_di_io_irq_start(me_subdevice_t * subdevice,
118                                   struct file *filep,
119                                   int channel,
120                                   int irq_source,
121                                   int irq_edge, int irq_arg, int flags)
122 {
123         me8100_di_subdevice_t *instance;
124         int err = ME_ERRNO_SUCCESS;
125         uint16_t ctrl;
126         unsigned long cpu_flags;
127
128         PDEBUG("executed.\n");
129
130         instance = (me8100_di_subdevice_t *) subdevice;
131
132         if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
133                 if (flags &
134                     ~(ME_IO_IRQ_START_PATTERN_FILTERING |
135                       ME_IO_IRQ_START_DIO_WORD)) {
136                         PERROR("Invalid flag specified.\n");
137                         return ME_ERRNO_INVALID_FLAGS;
138                 }
139
140                 if (irq_edge != ME_IRQ_EDGE_NOT_USED) {
141                         PERROR("Invalid irq edge specified.\n");
142                         return ME_ERRNO_INVALID_IRQ_EDGE;
143                 }
144         } else if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
145                 if (flags &
146                     ~(ME_IO_IRQ_START_EXTENDED_STATUS |
147                       ME_IO_IRQ_START_DIO_WORD)) {
148                         PERROR("Invalid flag specified.\n");
149                         return ME_ERRNO_INVALID_FLAGS;
150                 }
151
152                 if (irq_edge != ME_IRQ_EDGE_ANY) {
153                         PERROR("Invalid irq edge specified.\n");
154                         return ME_ERRNO_INVALID_IRQ_EDGE;
155                 }
156
157                 if (!(irq_arg & 0xFFFF)) {
158                         PERROR("No mask specified.\n");
159                         return ME_ERRNO_INVALID_IRQ_ARG;
160                 }
161         } else {
162                 PERROR("Invalid irq source specified.\n");
163                 return ME_ERRNO_INVALID_IRQ_SOURCE;
164         }
165
166         if (channel) {
167                 PERROR("Invalid channel specified.\n");
168                 return ME_ERRNO_INVALID_CHANNEL;
169         }
170
171         ME_SUBDEVICE_ENTER;
172
173         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
174         if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
175                 outw(irq_arg, instance->pattern_reg);
176                 instance->compare_value = irq_arg;
177                 instance->filtering_flag =
178                     (flags & ME_IO_IRQ_START_PATTERN_FILTERING) ? 1 : 0;
179         }
180         if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
181                 outw(irq_arg, instance->mask_reg);
182         }
183
184         spin_lock(instance->ctrl_reg_lock);
185         ctrl = inw(instance->ctrl_reg);
186         ctrl |= ME8100_DIO_CTRL_BIT_INTB_0;
187         if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
188                 ctrl &= ~ME8100_DIO_CTRL_BIT_INTB_1;
189         }
190
191         if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
192                 ctrl |= ME8100_DIO_CTRL_BIT_INTB_1;
193         }
194         outw(ctrl, instance->ctrl_reg);
195         PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
196                    instance->ctrl_reg - instance->reg_base, ctrl);
197         spin_unlock(instance->ctrl_reg_lock);
198
199         instance->rised = 0;
200         instance->status_value = 0;
201         instance->status_value_edges = 0;
202         instance->line_value = inw(instance->port_reg);
203         instance->status_flag = flags & ME_IO_IRQ_START_EXTENDED_STATUS;
204         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
205
206         ME_SUBDEVICE_EXIT;
207
208         return err;
209 }
210
211 static int me8100_di_io_irq_wait(me_subdevice_t * subdevice,
212                                  struct file *filep,
213                                  int channel,
214                                  int *irq_count,
215                                  int *value, int time_out, int flags)
216 {
217         me8100_di_subdevice_t *instance;
218         int err = ME_ERRNO_SUCCESS;
219         long t = 0;
220         unsigned long cpu_flags;
221         int count;
222
223         PDEBUG("executed.\n");
224         PDEVELOP("PID: %d.\n", current->pid);
225
226         instance = (me8100_di_subdevice_t *) subdevice;
227
228         if (flags &
229             ~(ME_IO_IRQ_WAIT_NORMAL_STATUS | ME_IO_IRQ_WAIT_EXTENDED_STATUS)) {
230                 PERROR("Invalid flag specified.\n");
231                 return ME_ERRNO_INVALID_FLAGS;
232         }
233
234         if (channel) {
235                 PERROR("Invalid channel specified.\n");
236                 return ME_ERRNO_INVALID_CHANNEL;
237         }
238
239         if (time_out < 0) {
240                 PERROR("Invalid time_out specified.\n");
241                 return ME_ERRNO_INVALID_TIMEOUT;
242         }
243
244         if (time_out) {
245                 t = (time_out * HZ) / 1000;
246
247                 if (t == 0)
248                         t = 1;
249         }
250
251         ME_SUBDEVICE_ENTER;
252
253         if (instance->rised <= 0) {
254                 instance->rised = 0;
255                 count = instance->irq_count;
256
257                 if (time_out) {
258                         t = wait_event_interruptible_timeout(instance->
259                                                              wait_queue,
260                                                              ((count !=
261                                                                instance->
262                                                                irq_count)
263                                                               || (instance->
264                                                                   rised < 0)),
265                                                              t);
266 //                      t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t);
267                         if (t == 0) {
268                                 PERROR("Wait on interrupt timed out.\n");
269                                 err = ME_ERRNO_TIMEOUT;
270                         }
271                 } else {
272                         wait_event_interruptible(instance->wait_queue,
273                                                  ((count != instance->irq_count)
274                                                   || (instance->rised < 0)));
275 //                      wait_event_interruptible(instance->wait_queue, (instance->rised != 0));
276                 }
277
278                 if (instance->rised < 0) {
279                         PERROR("Wait on interrupt aborted by user.\n");
280                         err = ME_ERRNO_CANCELLED;
281                 }
282         }
283
284         if (signal_pending(current)) {
285                 PERROR("Wait on interrupt aborted by signal.\n");
286                 err = ME_ERRNO_SIGNAL;
287         }
288
289         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
290         *irq_count = instance->irq_count;
291         if (!err) {
292                 if (flags & ME_IO_IRQ_WAIT_NORMAL_STATUS) {
293                         *value = instance->status_value;
294                 } else if (flags & ME_IO_IRQ_WAIT_EXTENDED_STATUS) {
295                         *value = instance->status_value_edges;
296                 } else {        // Use default
297                         if (!instance->status_flag) {
298                                 *value = instance->status_value;
299                         } else {
300                                 *value = instance->status_value_edges;
301                         }
302                 }
303                 instance->rised = 0;
304 /*
305                         instance->status_value = 0;
306                         instance->status_value_edges = 0;
307 */
308         } else {
309                 *value = 0;
310         }
311         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
312
313         ME_SUBDEVICE_EXIT;
314
315         return err;
316 }
317
318 static int me8100_di_io_irq_stop(me_subdevice_t * subdevice,
319                                  struct file *filep, int channel, int flags)
320 {
321         me8100_di_subdevice_t *instance;
322         uint16_t ctrl;
323         unsigned long cpu_flags;
324
325         PDEBUG("executed.\n");
326
327         instance = (me8100_di_subdevice_t *) subdevice;
328
329         if (flags) {
330                 PERROR("Invalid flag specified.\n");
331                 return ME_ERRNO_INVALID_FLAGS;
332         }
333
334         if (channel) {
335                 PERROR("Invalid channel specified.\n");
336                 return ME_ERRNO_INVALID_CHANNEL;
337         }
338
339         ME_SUBDEVICE_ENTER;
340
341         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
342         spin_lock(instance->ctrl_reg_lock);
343         ctrl = inw(instance->ctrl_reg);
344         ctrl &= ~(ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0);
345         outw(ctrl, instance->ctrl_reg);
346         PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
347                    instance->ctrl_reg - instance->reg_base, ctrl);
348         spin_unlock(instance->ctrl_reg_lock);
349         instance->rised = -1;
350         instance->status_value = 0;
351         instance->status_value_edges = 0;
352         instance->filtering_flag = 0;
353         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
354         wake_up_interruptible_all(&instance->wait_queue);
355
356         ME_SUBDEVICE_EXIT;
357
358         return ME_ERRNO_SUCCESS;
359 }
360
361 static int me8100_di_io_single_config(me_subdevice_t * subdevice,
362                                       struct file *filep,
363                                       int channel,
364                                       int single_config,
365                                       int ref,
366                                       int trig_chan,
367                                       int trig_type, int trig_edge, int flags)
368 {
369         me8100_di_subdevice_t *instance;
370         int err = ME_ERRNO_SUCCESS;
371
372         PDEBUG("executed.\n");
373
374         instance = (me8100_di_subdevice_t *) subdevice;
375
376         ME_SUBDEVICE_ENTER;
377
378         spin_lock(&instance->subdevice_lock);
379
380         switch (flags) {
381         case ME_IO_SINGLE_CONFIG_NO_FLAGS:
382         case ME_IO_SINGLE_CONFIG_DIO_WORD:
383                 if (channel == 0) {
384                         if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
385                         } else {
386                                 PERROR
387                                     ("Invalid port configuration specified.\n");
388                                 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
389                         }
390                 } else {
391                         PERROR("Invalid channel number.\n");
392                         err = ME_ERRNO_INVALID_CHANNEL;
393                 }
394                 break;
395
396         default:
397                 PERROR("Invalid flags specified.\n");
398                 err = ME_ERRNO_INVALID_FLAGS;
399         }
400
401         spin_unlock(&instance->subdevice_lock);
402
403         ME_SUBDEVICE_EXIT;
404
405         return err;
406 }
407
408 static int me8100_di_io_single_read(me_subdevice_t * subdevice,
409                                     struct file *filep,
410                                     int channel,
411                                     int *value, int time_out, int flags)
412 {
413         me8100_di_subdevice_t *instance;
414         int err = ME_ERRNO_SUCCESS;
415
416         PDEBUG("executed.\n");
417
418         instance = (me8100_di_subdevice_t *) subdevice;
419
420         ME_SUBDEVICE_ENTER;
421
422         spin_lock(&instance->subdevice_lock);
423
424         switch (flags) {
425
426         case ME_IO_SINGLE_TYPE_DIO_BIT:
427                 if ((channel >= 0) && (channel < 16)) {
428                         *value = inw(instance->port_reg) & (0x1 << channel);
429                 } else {
430                         PERROR("Invalid bit number specified.\n");
431                         err = ME_ERRNO_INVALID_CHANNEL;
432                 }
433                 break;
434
435         case ME_IO_SINGLE_TYPE_DIO_BYTE:
436                 if (channel == 0) {
437                         *value = inw(instance->port_reg) & 0xFF;
438                 } else if (channel == 1) {
439                         *value = (inw(instance->port_reg) >> 8) & 0xFF;
440                 } else {
441                         PERROR("Invalid byte number specified.\n");
442                         err = ME_ERRNO_INVALID_CHANNEL;
443                 }
444                 break;
445
446         case ME_IO_SINGLE_NO_FLAGS:
447         case ME_IO_SINGLE_TYPE_DIO_WORD:
448                 if (channel == 0) {
449                         *value = inw(instance->port_reg);
450                 } else {
451                         PERROR("Invalid word number specified.\n");
452                         err = ME_ERRNO_INVALID_CHANNEL;
453                 }
454
455                 break;
456
457         default:
458                 PERROR("Invalid flags specified.\n");
459                 err = ME_ERRNO_INVALID_FLAGS;
460         }
461
462         spin_unlock(&instance->subdevice_lock);
463
464         ME_SUBDEVICE_EXIT;
465
466         return err;
467 }
468
469 static int me8100_di_query_number_channels(me_subdevice_t * subdevice,
470                                            int *number)
471 {
472         PDEBUG("executed.\n");
473         *number = 16;
474         return ME_ERRNO_SUCCESS;
475 }
476
477 static int me8100_di_query_subdevice_type(me_subdevice_t * subdevice,
478                                           int *type, int *subtype)
479 {
480         PDEBUG("executed.\n");
481         *type = ME_TYPE_DI;
482         *subtype = ME_SUBTYPE_SINGLE;
483         return ME_ERRNO_SUCCESS;
484 }
485
486 static int me8100_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
487 {
488         PDEBUG("executed.\n");
489         *caps = ME_CAPS_DIO_BIT_PATTERN_IRQ | ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY;
490         return ME_ERRNO_SUCCESS;
491 }
492
493 static void me8100_di_destructor(struct me_subdevice *subdevice)
494 {
495         me8100_di_subdevice_t *instance;
496
497         PDEBUG("executed.\n");
498
499         instance = (me8100_di_subdevice_t *) subdevice;
500
501         free_irq(instance->irq, (void *)instance);
502         me_subdevice_deinit(&instance->base);
503         kfree(instance);
504 }
505
506 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
507 static irqreturn_t me8100_isr(int irq, void *dev_id)
508 #else
509 static irqreturn_t me8100_isr(int irq, void *dev_id, struct pt_regs *regs)
510 #endif
511 {
512         me8100_di_subdevice_t *instance;
513         uint32_t icsr;
514
515         uint16_t irq_status;
516         uint16_t line_value = 0;
517
518         uint32_t status_val = 0;
519
520         PDEBUG("executed.\n");
521
522         instance = (me8100_di_subdevice_t *) dev_id;
523
524         if (irq != instance->irq) {
525                 PERROR("Incorrect interrupt num: %d.\n", irq);
526                 return IRQ_NONE;
527         }
528
529         icsr = inl(instance->irq_status_reg);
530         if (instance->di_idx == 0) {
531
532                 if ((icsr &
533                      (PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_PCI_INT_EN |
534                       PLX_INTCSR_LOCAL_INT1_EN)) !=
535                     (PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_PCI_INT_EN |
536                      PLX_INTCSR_LOCAL_INT1_EN)) {
537                         PINFO
538                             ("%ld Shared interrupt. %s(): idx=0 plx:irq_status_reg=0x%04X\n",
539                              jiffies, __func__, icsr);
540                         return IRQ_NONE;
541                 }
542         } else if (instance->di_idx == 1) {
543                 if ((icsr &
544                      (PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_PCI_INT_EN |
545                       PLX_INTCSR_LOCAL_INT2_EN)) !=
546                     (PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_PCI_INT_EN |
547                      PLX_INTCSR_LOCAL_INT2_EN)) {
548                         PINFO
549                             ("%ld Shared interrupt. %s(): idx=1 plx:irq_status_reg=0x%04X\n",
550                              jiffies, __func__, icsr);
551                         return IRQ_NONE;
552                 }
553         } else {
554                 PERROR("%s():Wrong interrupt idx=%d csr=0x%X.\n", __func__,
555                        instance->di_idx, icsr);
556                 return IRQ_NONE;
557         }
558
559         PDEBUG("me8100_isr():Interrupt from idx=%d occured.\n",
560                instance->di_idx);
561         spin_lock(&instance->subdevice_lock);
562         inw(instance->irq_reset_reg);
563         line_value = inw(instance->port_reg);
564
565         irq_status = instance->line_value ^ line_value;
566
567         // Make extended information.
568         status_val |= (0x00FF & (~(uint16_t) instance->line_value & line_value)) << 16; //Raise
569         status_val |= (0x00FF & ((uint16_t) instance->line_value & ~line_value));       //Fall
570
571         instance->line_value = line_value;
572
573         if (instance->rised == 0) {
574                 instance->status_value = irq_status;
575                 instance->status_value_edges = status_val;
576         } else {
577                 instance->status_value |= irq_status;
578                 instance->status_value_edges |= status_val;
579         }
580
581         if (instance->filtering_flag) { // For compare mode only.
582                 if (instance->compare_value == instance->line_value) {
583                         instance->rised = 1;
584                         instance->irq_count++;
585                 }
586         } else {
587                 instance->rised = 1;
588                 instance->irq_count++;
589         }
590
591         spin_unlock(&instance->subdevice_lock);
592         wake_up_interruptible_all(&instance->wait_queue);
593
594         return IRQ_HANDLED;
595 }
596
597 me8100_di_subdevice_t *me8100_di_constructor(uint32_t me8100_reg_base,
598                                              uint32_t plx_reg_base,
599                                              unsigned int di_idx,
600                                              int irq,
601                                              spinlock_t * ctrl_reg_lock)
602 {
603         me8100_di_subdevice_t *subdevice;
604         int err;
605
606         PDEBUG("executed.\n");
607
608         /* Allocate memory for subdevice instance */
609         subdevice = kmalloc(sizeof(me8100_di_subdevice_t), GFP_KERNEL);
610
611         if (!subdevice) {
612                 PERROR("Cannot get memory for subdevice instance.\n");
613                 return NULL;
614         }
615
616         memset(subdevice, 0, sizeof(me8100_di_subdevice_t));
617
618         /* Initialize subdevice base class */
619         err = me_subdevice_init(&subdevice->base);
620
621         if (err) {
622                 PERROR("Cannot initialize subdevice base class instance.\n");
623                 kfree(subdevice);
624                 return NULL;
625         }
626         // Initialize spin locks.
627         spin_lock_init(&subdevice->subdevice_lock);
628
629         subdevice->ctrl_reg_lock = ctrl_reg_lock;
630
631         /* Save the subdevice index. */
632         subdevice->di_idx = di_idx;
633
634         /* Initialize wait queue */
635         init_waitqueue_head(&subdevice->wait_queue);
636
637         /* Register interrupt service routine. */
638         subdevice->irq = irq;
639         err = request_irq(subdevice->irq, me8100_isr,
640 #ifdef IRQF_DISABLED
641                           IRQF_DISABLED | IRQF_SHARED,
642 #else
643                           SA_INTERRUPT | SA_SHIRQ,
644 #endif
645                           ME8100_NAME, (void *)subdevice);
646
647         if (err) {
648                 PERROR("Cannot initialize subdevice base class instance.\n");
649                 kfree(subdevice);
650                 return NULL;
651         }
652         PINFO("Registered irq=%d.\n", subdevice->irq);
653
654         /* Initialize the registers */
655         subdevice->ctrl_reg =
656             me8100_reg_base + ME8100_CTRL_REG_A + di_idx * ME8100_REG_OFFSET;
657         subdevice->port_reg =
658             me8100_reg_base + ME8100_DI_REG_A + di_idx * ME8100_REG_OFFSET;
659         subdevice->mask_reg =
660             me8100_reg_base + ME8100_MASK_REG_A + di_idx * ME8100_REG_OFFSET;
661         subdevice->pattern_reg =
662             me8100_reg_base + ME8100_PATTERN_REG_A + di_idx * ME8100_REG_OFFSET;
663         subdevice->din_int_reg =
664             me8100_reg_base + ME8100_INT_DI_REG_A + di_idx * ME8100_REG_OFFSET;
665         subdevice->irq_reset_reg =
666             me8100_reg_base + ME8100_RES_INT_REG_A + di_idx * ME8100_REG_OFFSET;
667         subdevice->irq_status_reg = plx_reg_base + PLX_INTCSR;
668 #ifdef MEDEBUG_DEBUG_REG
669         subdevice->reg_base = me8100_reg_base;
670 #endif
671
672         /* Overload base class methods. */
673         subdevice->base.me_subdevice_io_irq_start = me8100_di_io_irq_start;
674         subdevice->base.me_subdevice_io_irq_wait = me8100_di_io_irq_wait;
675         subdevice->base.me_subdevice_io_irq_stop = me8100_di_io_irq_stop;
676         subdevice->base.me_subdevice_io_reset_subdevice =
677             me8100_di_io_reset_subdevice;
678         subdevice->base.me_subdevice_io_single_config =
679             me8100_di_io_single_config;
680         subdevice->base.me_subdevice_io_single_read = me8100_di_io_single_read;
681         subdevice->base.me_subdevice_query_number_channels =
682             me8100_di_query_number_channels;
683         subdevice->base.me_subdevice_query_subdevice_type =
684             me8100_di_query_subdevice_type;
685         subdevice->base.me_subdevice_query_subdevice_caps =
686             me8100_di_query_subdevice_caps;
687         subdevice->base.me_subdevice_destructor = me8100_di_destructor;
688
689         subdevice->rised = 0;
690         subdevice->irq_count = 0;
691
692         return subdevice;
693 }