4 * @brief 8255 subdevice instance.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
12 * This file is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 #include <linux/module.h>
36 #include <linux/slab.h>
37 #include <linux/spinlock.h>
39 #include <linux/types.h>
41 #include "medefines.h"
42 #include "meinternal.h"
46 #include "me8255_reg.h"
57 static uint8_t get_mode_from_mirror(uint32_t mirror
)
59 PDEBUG("executed.\n");
61 if (mirror
& ME8255_PORT_0_OUTPUT
) {
62 if (mirror
& ME8255_PORT_1_OUTPUT
) {
63 if (mirror
& ME8255_PORT_2_OUTPUT
) {
64 return ME8255_MODE_OOO
;
66 return ME8255_MODE_IOO
;
69 if (mirror
& ME8255_PORT_2_OUTPUT
) {
70 return ME8255_MODE_OIO
;
72 return ME8255_MODE_IIO
;
76 if (mirror
& ME8255_PORT_1_OUTPUT
) {
77 if (mirror
& ME8255_PORT_2_OUTPUT
) {
78 return ME8255_MODE_OOI
;
80 return ME8255_MODE_IOI
;
83 if (mirror
& ME8255_PORT_2_OUTPUT
) {
84 return ME8255_MODE_OII
;
86 return ME8255_MODE_III
;
92 static int me8255_io_reset_subdevice(struct me_subdevice
*subdevice
,
93 struct file
*filep
, int flags
)
95 me8255_subdevice_t
*instance
;
97 PDEBUG("executed.\n");
99 instance
= (me8255_subdevice_t
*) subdevice
;
102 PERROR("Invalid flag specified.\n");
103 return ME_ERRNO_INVALID_FLAGS
;
108 spin_lock(&instance
->subdevice_lock
);
109 spin_lock(instance
->ctrl_reg_lock
);
110 *instance
->ctrl_reg_mirror
&=
111 ~(ME8255_PORT_0_OUTPUT
<< instance
->dio_idx
);
112 outb(get_mode_from_mirror(*instance
->ctrl_reg_mirror
),
114 spin_unlock(instance
->ctrl_reg_lock
);
116 outb(0, instance
->port_reg
);
117 spin_unlock(&instance
->subdevice_lock
);
121 return ME_ERRNO_SUCCESS
;
124 static int me8255_io_single_config(struct me_subdevice
*subdevice
,
130 int trig_type
, int trig_edge
, int flags
)
132 me8255_subdevice_t
*instance
;
133 int err
= ME_ERRNO_SUCCESS
;
135 PDEBUG("executed.\n");
137 instance
= (me8255_subdevice_t
*) subdevice
;
139 if (flags
& ~ME_IO_SINGLE_CONFIG_DIO_BYTE
) {
140 PERROR("Invalid flag specified.\n");
141 return ME_ERRNO_INVALID_FLAGS
;
145 PERROR("Invalid channel.\n");
146 return ME_ERRNO_INVALID_CHANNEL
;
151 spin_lock(&instance
->subdevice_lock
);
152 if (single_config
== ME_SINGLE_CONFIG_DIO_INPUT
) {
153 spin_lock(instance
->ctrl_reg_lock
);
154 *instance
->ctrl_reg_mirror
&=
155 ~(ME8255_PORT_0_OUTPUT
<< instance
->dio_idx
);
156 outb(get_mode_from_mirror(*instance
->ctrl_reg_mirror
),
158 spin_unlock(instance
->ctrl_reg_lock
);
159 } else if (single_config
== ME_SINGLE_CONFIG_DIO_OUTPUT
) {
160 spin_lock(instance
->ctrl_reg_lock
);
161 *instance
->ctrl_reg_mirror
|=
162 (ME8255_PORT_0_OUTPUT
<< instance
->dio_idx
);
163 outb(get_mode_from_mirror(*instance
->ctrl_reg_mirror
),
165 spin_unlock(instance
->ctrl_reg_lock
);
167 PERROR("Invalid port direction.\n");
168 err
= ME_ERRNO_INVALID_SINGLE_CONFIG
;
170 spin_unlock(&instance
->subdevice_lock
);
177 static int me8255_io_single_read(struct me_subdevice
*subdevice
,
180 int *value
, int time_out
, int flags
)
182 me8255_subdevice_t
*instance
;
183 int err
= ME_ERRNO_SUCCESS
;
185 PDEBUG("executed.\n");
187 instance
= (me8255_subdevice_t
*) subdevice
;
191 spin_lock(&instance
->subdevice_lock
);
193 case ME_IO_SINGLE_TYPE_DIO_BIT
:
194 if ((channel
>= 0) && (channel
< 8)) {
195 *value
= inb(instance
->port_reg
) & (0x1 << channel
);
197 PERROR("Invalid bit number.\n");
198 err
= ME_ERRNO_INVALID_CHANNEL
;
202 case ME_IO_SINGLE_NO_FLAGS
:
203 case ME_IO_SINGLE_TYPE_DIO_BYTE
:
205 *value
= inb(instance
->port_reg
);
207 PERROR("Invalid byte number.\n");
208 err
= ME_ERRNO_INVALID_CHANNEL
;
213 PERROR("Invalid flags specified.\n");
214 err
= ME_ERRNO_INVALID_FLAGS
;
216 spin_unlock(&instance
->subdevice_lock
);
223 static int me8255_io_single_write(struct me_subdevice
*subdevice
,
226 int value
, int time_out
, int flags
)
228 me8255_subdevice_t
*instance
;
230 int err
= ME_ERRNO_SUCCESS
;
232 PDEBUG("executed.\n");
234 instance
= (me8255_subdevice_t
*) subdevice
;
238 spin_lock(&instance
->subdevice_lock
);
240 case ME_IO_SINGLE_TYPE_DIO_BIT
:
241 if ((channel
>= 0) && (channel
< 8)) {
243 ctrl_reg_mirror
& (ME8255_PORT_0_OUTPUT
<<
244 instance
->dio_idx
)) {
245 byte
= inb(instance
->port_reg
);
248 byte
|= 0x1 << channel
;
250 byte
&= ~(0x1 << channel
);
252 outb(byte
, instance
->port_reg
);
254 PERROR("Port not in output mode.\n");
255 err
= ME_ERRNO_PREVIOUS_CONFIG
;
258 PERROR("Invalid bit number.\n");
259 err
= ME_ERRNO_INVALID_CHANNEL
;
263 case ME_IO_SINGLE_NO_FLAGS
:
264 case ME_IO_SINGLE_TYPE_DIO_BYTE
:
267 ctrl_reg_mirror
& (ME8255_PORT_0_OUTPUT
<<
268 instance
->dio_idx
)) {
269 outb(value
, instance
->port_reg
);
271 PERROR("Port not in output mode.\n");
272 err
= ME_ERRNO_PREVIOUS_CONFIG
;
275 PERROR("Invalid byte number.\n");
276 err
= ME_ERRNO_INVALID_CHANNEL
;
281 PERROR("Invalid flags specified.\n");
282 err
= ME_ERRNO_INVALID_FLAGS
;
284 spin_unlock(&instance
->subdevice_lock
);
291 static int me8255_query_number_channels(struct me_subdevice
*subdevice
,
294 PDEBUG("executed.\n");
295 *number
= ME8255_NUMBER_CHANNELS
;
296 return ME_ERRNO_SUCCESS
;
299 static int me8255_query_subdevice_type(struct me_subdevice
*subdevice
,
300 int *type
, int *subtype
)
302 PDEBUG("executed.\n");
304 *subtype
= ME_SUBTYPE_SINGLE
;
305 return ME_ERRNO_SUCCESS
;
308 static int me8255_query_subdevice_caps(struct me_subdevice
*subdevice
,
311 PDEBUG("executed.\n");
312 *caps
= ME_CAPS_DIO_DIR_BYTE
;
313 return ME_ERRNO_SUCCESS
;
316 me8255_subdevice_t
*me8255_constructor(uint32_t device_id
,
318 unsigned int me8255_idx
,
319 unsigned int dio_idx
,
320 int *ctrl_reg_mirror
,
321 spinlock_t
*ctrl_reg_lock
)
323 me8255_subdevice_t
*subdevice
;
326 PDEBUG("executed.\n");
328 /* Allocate memory for subdevice instance */
329 subdevice
= kmalloc(sizeof(me8255_subdevice_t
), GFP_KERNEL
);
332 PERROR("Cannot get memory for 8255 instance.\n");
336 memset(subdevice
, 0, sizeof(me8255_subdevice_t
));
338 /* Check if counter index is out of range */
341 PERROR("DIO index is out of range.\n");
346 /* Initialize subdevice base class */
347 err
= me_subdevice_init(&subdevice
->base
);
350 PERROR("Cannot initialize subdevice base class instance.\n");
354 // Initialize spin locks.
355 spin_lock_init(&subdevice
->subdevice_lock
);
357 subdevice
->ctrl_reg_lock
= ctrl_reg_lock
;
359 /* Save the pointer to global port settings */
360 subdevice
->ctrl_reg_mirror
= ctrl_reg_mirror
;
362 /* Save type of Meilhaus device */
363 subdevice
->device_id
= device_id
;
365 /* Save the indices */
366 subdevice
->me8255_idx
= me8255_idx
;
367 subdevice
->dio_idx
= dio_idx
;
369 /* Do device specific initialization */
371 case PCI_DEVICE_ID_MEILHAUS_ME1400
:
372 case PCI_DEVICE_ID_MEILHAUS_ME14E0
:
374 case PCI_DEVICE_ID_MEILHAUS_ME140A
:
375 case PCI_DEVICE_ID_MEILHAUS_ME14EA
:
376 /* Check if 8255 index is out of range */
377 if (me8255_idx
> 0) {
378 PERROR("8255 index is out of range.\n");
379 me_subdevice_deinit(&subdevice
->base
);
384 case PCI_DEVICE_ID_MEILHAUS_ME140B
: /* Fall through */
385 case PCI_DEVICE_ID_MEILHAUS_ME14EB
:
386 /* Check if 8255 index is out of range */
387 if (me8255_idx
> 1) {
388 PERROR("8255 index is out of range.\n");
389 me_subdevice_deinit(&subdevice
->base
);
394 /* Get the registers */
395 if (me8255_idx
== 0) {
396 subdevice
->ctrl_reg
= reg_base
+ ME1400AB_PORT_A_CTRL
;
397 subdevice
->port_reg
=
398 reg_base
+ ME1400AB_PORT_A_0
+ dio_idx
;
399 } else if (me8255_idx
== 1) {
400 subdevice
->ctrl_reg
= reg_base
+ ME1400AB_PORT_B_CTRL
;
401 subdevice
->port_reg
=
402 reg_base
+ ME1400AB_PORT_B_0
+ dio_idx
;
407 case PCI_DEVICE_ID_MEILHAUS_ME140C
:
408 /* Check if 8255 index is out of range */
409 if (me8255_idx
> 0) {
410 PERROR("8255 index is out of range.\n");
411 me_subdevice_deinit(&subdevice
->base
);
416 case PCI_DEVICE_ID_MEILHAUS_ME140D
: /* Fall through */
417 /* Check if 8255 index is out of range */
418 if (me8255_idx
> 1) {
419 PERROR("8255 index is out of range.\n");
420 me_subdevice_deinit(&subdevice
->base
);
425 /* Get the registers */
426 if (me8255_idx
== 0) {
427 subdevice
->ctrl_reg
= reg_base
+ ME1400CD_PORT_A_CTRL
;
428 subdevice
->port_reg
=
429 reg_base
+ ME1400CD_PORT_A_0
+ dio_idx
;
430 } else if (me8255_idx
== 1) {
431 subdevice
->ctrl_reg
= reg_base
+ ME1400CD_PORT_B_CTRL
;
432 subdevice
->port_reg
=
433 reg_base
+ ME1400CD_PORT_B_0
+ dio_idx
;
439 PERROR("Unknown device type. dev ID: 0x%04x\n", device_id
);
441 me_subdevice_deinit(&subdevice
->base
);
448 /* Overload subdevice base class methods. */
449 subdevice
->base
.me_subdevice_io_reset_subdevice
=
450 me8255_io_reset_subdevice
;
451 subdevice
->base
.me_subdevice_io_single_config
= me8255_io_single_config
;
452 subdevice
->base
.me_subdevice_io_single_read
= me8255_io_single_read
;
453 subdevice
->base
.me_subdevice_io_single_write
= me8255_io_single_write
;
454 subdevice
->base
.me_subdevice_query_number_channels
=
455 me8255_query_number_channels
;
456 subdevice
->base
.me_subdevice_query_subdevice_type
=
457 me8255_query_subdevice_type
;
458 subdevice
->base
.me_subdevice_query_subdevice_caps
=
459 me8255_query_subdevice_caps
;