aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Kiliani <mail@davidkiliani.de>2008-10-31 19:39:12 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 16:52:29 -0500
commit3fedd14818592016f7ffd84dfe134881b3896ecf (patch)
tree22574873dc7d844d4cc33d04f7e6ba03f23c639e /drivers
parent5ec5ec78060481e6a0cecc06ab0c6ec8b213ec80 (diff)
Staging: Add the Meilhaus ME-IDS driver package
Originally written by Guenter Gebhardt <g.gebhardt@meilhaus.de> and Krzysztof Gantzke <k.gantzke@meilhaus.de> This is the drv/lnx/mod directory of ME-IDS 1.2.9 tarball with some files from drv/lnx/include. Signed-off-by: David Kiliani <mail@davidkiliani.de> Cc: Guenter Gebhardt <g.gebhardt@meilhaus.de> Cc: Krzysztof Gantzke <k.gantzke@meilhaus.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/meilhaus/Kconfig127
-rw-r--r--drivers/staging/meilhaus/Makefile43
-rw-r--r--drivers/staging/meilhaus/TODO10
-rw-r--r--drivers/staging/meilhaus/me0600_device.c215
-rw-r--r--drivers/staging/meilhaus/me0600_device.h97
-rw-r--r--drivers/staging/meilhaus/me0600_dio.c415
-rw-r--r--drivers/staging/meilhaus/me0600_dio.h68
-rw-r--r--drivers/staging/meilhaus/me0600_dio_reg.h41
-rw-r--r--drivers/staging/meilhaus/me0600_ext_irq.c478
-rw-r--r--drivers/staging/meilhaus/me0600_ext_irq.h58
-rw-r--r--drivers/staging/meilhaus/me0600_ext_irq_reg.h18
-rw-r--r--drivers/staging/meilhaus/me0600_optoi.c243
-rw-r--r--drivers/staging/meilhaus/me0600_optoi.h58
-rw-r--r--drivers/staging/meilhaus/me0600_optoi_reg.h35
-rw-r--r--drivers/staging/meilhaus/me0600_relay.c359
-rw-r--r--drivers/staging/meilhaus/me0600_relay.h63
-rw-r--r--drivers/staging/meilhaus/me0600_relay_reg.h36
-rw-r--r--drivers/staging/meilhaus/me0600_ttli.c238
-rw-r--r--drivers/staging/meilhaus/me0600_ttli.h58
-rw-r--r--drivers/staging/meilhaus/me0600_ttli_reg.h35
-rw-r--r--drivers/staging/meilhaus/me0900_device.c180
-rw-r--r--drivers/staging/meilhaus/me0900_device.h92
-rw-r--r--drivers/staging/meilhaus/me0900_di.c246
-rw-r--r--drivers/staging/meilhaus/me0900_di.h65
-rw-r--r--drivers/staging/meilhaus/me0900_do.c314
-rw-r--r--drivers/staging/meilhaus/me0900_do.h68
-rw-r--r--drivers/staging/meilhaus/me0900_reg.h40
-rw-r--r--drivers/staging/meilhaus/me1000_device.c208
-rw-r--r--drivers/staging/meilhaus/me1000_device.h59
-rw-r--r--drivers/staging/meilhaus/me1000_dio.c438
-rw-r--r--drivers/staging/meilhaus/me1000_dio.h71
-rw-r--r--drivers/staging/meilhaus/me1000_dio_reg.h50
-rw-r--r--drivers/staging/meilhaus/me1400_device.c256
-rw-r--r--drivers/staging/meilhaus/me1400_device.h108
-rw-r--r--drivers/staging/meilhaus/me1400_ext_irq.c517
-rw-r--r--drivers/staging/meilhaus/me1400_ext_irq.h62
-rw-r--r--drivers/staging/meilhaus/me1400_ext_irq_reg.h56
-rw-r--r--drivers/staging/meilhaus/me1600_ao.c1033
-rw-r--r--drivers/staging/meilhaus/me1600_ao.h132
-rw-r--r--drivers/staging/meilhaus/me1600_ao_reg.h66
-rw-r--r--drivers/staging/meilhaus/me1600_device.c261
-rw-r--r--drivers/staging/meilhaus/me1600_device.h101
-rw-r--r--drivers/staging/meilhaus/me4600_ai.c3434
-rw-r--r--drivers/staging/meilhaus/me4600_ai.h180
-rw-r--r--drivers/staging/meilhaus/me4600_ai_reg.h107
-rw-r--r--drivers/staging/meilhaus/me4600_ao.c6011
-rw-r--r--drivers/staging/meilhaus/me4600_ao.h263
-rw-r--r--drivers/staging/meilhaus/me4600_ao_reg.h113
-rw-r--r--drivers/staging/meilhaus/me4600_device.c373
-rw-r--r--drivers/staging/meilhaus/me4600_device.h151
-rw-r--r--drivers/staging/meilhaus/me4600_di.c256
-rw-r--r--drivers/staging/meilhaus/me4600_di.h64
-rw-r--r--drivers/staging/meilhaus/me4600_dio.c510
-rw-r--r--drivers/staging/meilhaus/me4600_dio.h69
-rw-r--r--drivers/staging/meilhaus/me4600_dio_reg.h63
-rw-r--r--drivers/staging/meilhaus/me4600_do.c433
-rw-r--r--drivers/staging/meilhaus/me4600_do.h65
-rw-r--r--drivers/staging/meilhaus/me4600_ext_irq.c467
-rw-r--r--drivers/staging/meilhaus/me4600_ext_irq.h78
-rw-r--r--drivers/staging/meilhaus/me4600_ext_irq_reg.h41
-rw-r--r--drivers/staging/meilhaus/me4600_reg.h46
-rw-r--r--drivers/staging/meilhaus/me6000_ao.c3739
-rw-r--r--drivers/staging/meilhaus/me6000_ao.h200
-rw-r--r--drivers/staging/meilhaus/me6000_ao_reg.h177
-rw-r--r--drivers/staging/meilhaus/me6000_device.c211
-rw-r--r--drivers/staging/meilhaus/me6000_device.h149
-rw-r--r--drivers/staging/meilhaus/me6000_dio.c415
-rw-r--r--drivers/staging/meilhaus/me6000_dio.h68
-rw-r--r--drivers/staging/meilhaus/me6000_dio_reg.h43
-rw-r--r--drivers/staging/meilhaus/me6000_reg.h35
-rw-r--r--drivers/staging/meilhaus/me8100_device.c187
-rw-r--r--drivers/staging/meilhaus/me8100_device.h97
-rw-r--r--drivers/staging/meilhaus/me8100_di.c693
-rw-r--r--drivers/staging/meilhaus/me8100_di.h89
-rw-r--r--drivers/staging/meilhaus/me8100_di_reg.h47
-rw-r--r--drivers/staging/meilhaus/me8100_do.c391
-rw-r--r--drivers/staging/meilhaus/me8100_do.h70
-rw-r--r--drivers/staging/meilhaus/me8100_do_reg.h36
-rw-r--r--drivers/staging/meilhaus/me8100_reg.h41
-rw-r--r--drivers/staging/meilhaus/me8200_device.c194
-rw-r--r--drivers/staging/meilhaus/me8200_device.h97
-rw-r--r--drivers/staging/meilhaus/me8200_di.c857
-rw-r--r--drivers/staging/meilhaus/me8200_di.h92
-rw-r--r--drivers/staging/meilhaus/me8200_di_reg.h75
-rw-r--r--drivers/staging/meilhaus/me8200_dio.c418
-rw-r--r--drivers/staging/meilhaus/me8200_dio.h68
-rw-r--r--drivers/staging/meilhaus/me8200_dio_reg.h43
-rw-r--r--drivers/staging/meilhaus/me8200_do.c600
-rw-r--r--drivers/staging/meilhaus/me8200_do.h75
-rw-r--r--drivers/staging/meilhaus/me8200_do_reg.h40
-rw-r--r--drivers/staging/meilhaus/me8200_reg.h46
-rw-r--r--drivers/staging/meilhaus/me8254.c1176
-rw-r--r--drivers/staging/meilhaus/me8254.h80
-rw-r--r--drivers/staging/meilhaus/me8254_reg.h172
-rw-r--r--drivers/staging/meilhaus/me8255.c462
-rw-r--r--drivers/staging/meilhaus/me8255.h59
-rw-r--r--drivers/staging/meilhaus/me8255_reg.h50
-rw-r--r--drivers/staging/meilhaus/mecirc_buf.h131
-rw-r--r--drivers/staging/meilhaus/mecommon.h26
-rw-r--r--drivers/staging/meilhaus/medebug.h125
-rw-r--r--drivers/staging/meilhaus/medefines.h449
-rw-r--r--drivers/staging/meilhaus/medevice.c1740
-rw-r--r--drivers/staging/meilhaus/medevice.h304
-rw-r--r--drivers/staging/meilhaus/medlist.c127
-rw-r--r--drivers/staging/meilhaus/medlist.h91
-rw-r--r--drivers/staging/meilhaus/medlock.c195
-rw-r--r--drivers/staging/meilhaus/medlock.h76
-rw-r--r--drivers/staging/meilhaus/medriver.h350
-rw-r--r--drivers/staging/meilhaus/medummy.c1266
-rw-r--r--drivers/staging/meilhaus/medummy.h40
-rw-r--r--drivers/staging/meilhaus/meerror.h100
-rw-r--r--drivers/staging/meilhaus/mefirmware.c137
-rw-r--r--drivers/staging/meilhaus/mefirmware.h57
-rw-r--r--drivers/staging/meilhaus/meids.h31
-rw-r--r--drivers/staging/meilhaus/meinternal.h363
-rw-r--r--drivers/staging/meilhaus/meioctl.h515
-rw-r--r--drivers/staging/meilhaus/memain.c2022
-rw-r--r--drivers/staging/meilhaus/memain.h460
-rw-r--r--drivers/staging/meilhaus/meplx_reg.h53
-rw-r--r--drivers/staging/meilhaus/meslist.c173
-rw-r--r--drivers/staging/meilhaus/meslist.h108
-rw-r--r--drivers/staging/meilhaus/meslock.c136
-rw-r--r--drivers/staging/meilhaus/meslock.h73
-rw-r--r--drivers/staging/meilhaus/mesubdevice.c317
-rw-r--r--drivers/staging/meilhaus/mesubdevice.h197
-rw-r--r--drivers/staging/meilhaus/metempl_device.c137
-rw-r--r--drivers/staging/meilhaus/metempl_device.h92
-rw-r--r--drivers/staging/meilhaus/metempl_sub.c149
-rw-r--r--drivers/staging/meilhaus/metempl_sub.h64
-rw-r--r--drivers/staging/meilhaus/metempl_sub_reg.h35
-rw-r--r--drivers/staging/meilhaus/metypes.h95
133 files changed, 41371 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index d8f26acf957b..a3e361db69fe 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -49,6 +49,8 @@ source "drivers/staging/sxg/Kconfig"
49 49
50source "drivers/staging/me4000/Kconfig" 50source "drivers/staging/me4000/Kconfig"
51 51
52source "drivers/staging/meilhaus/Kconfig"
53
52source "drivers/staging/go7007/Kconfig" 54source "drivers/staging/go7007/Kconfig"
53 55
54source "drivers/staging/usbip/Kconfig" 56source "drivers/staging/usbip/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index dd9a625d46b9..06613bb05085 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_ET131X) += et131x/
7obj-$(CONFIG_SLICOSS) += slicoss/ 7obj-$(CONFIG_SLICOSS) += slicoss/
8obj-$(CONFIG_SXG) += sxg/ 8obj-$(CONFIG_SXG) += sxg/
9obj-$(CONFIG_ME4000) += me4000/ 9obj-$(CONFIG_ME4000) += me4000/
10obj-$(CONFIG_MEILHAUS) += meilhaus/
10obj-$(CONFIG_VIDEO_GO7007) += go7007/ 11obj-$(CONFIG_VIDEO_GO7007) += go7007/
11obj-$(CONFIG_USB_IP_COMMON) += usbip/ 12obj-$(CONFIG_USB_IP_COMMON) += usbip/
12obj-$(CONFIG_W35UND) += winbond/ 13obj-$(CONFIG_W35UND) += winbond/
diff --git a/drivers/staging/meilhaus/Kconfig b/drivers/staging/meilhaus/Kconfig
new file mode 100644
index 000000000000..6def83fa2c96
--- /dev/null
+++ b/drivers/staging/meilhaus/Kconfig
@@ -0,0 +1,127 @@
1#
2# Meilhaus configuration
3#
4
5menuconfig MEILHAUS
6 tristate "Meilhaus support"
7 ---help---
8 If you have a Meilhaus card, say Y (or M) here.
9
10 You need both this driver, and the driver for the particular
11 data collection card.
12
13 To compile this driver as a module, choose M here. The module will
14 be called memain.
15
16if MEILHAUS
17
18config ME0600
19 tristate "Meilhaus ME-600 support"
20 default n
21 depends on PCI
22 help
23 This driver supports the Meilhaus ME-600 family of boards
24 that do data collection and multipurpose I/O.
25
26 To compile this driver as a module, choose M here: the module
27 will be called me0600.
28
29config ME0900
30 tristate "Meilhaus ME-900 support"
31 default n
32 depends on PCI
33 help
34 This driver supports the Meilhaus ME-900 family of boards
35 that do data collection and multipurpose I/O.
36
37 To compile this driver as a module, choose M here: the module
38 will be called me0900.
39
40config ME1000
41 tristate "Meilhaus ME-1000 support"
42 default n
43 depends on PCI
44 help
45 This driver supports the Meilhaus ME-1000 family of boards
46 that do data collection and multipurpose I/O.
47
48 To compile this driver as a module, choose M here: the module
49 will be called me1000.
50
51config ME1400
52 tristate "Meilhaus ME-1400 support"
53 default n
54 depends on PCI
55 help
56 This driver supports the Meilhaus ME-1400 family of boards
57 that do data collection and multipurpose I/O.
58
59 To compile this driver as a module, choose M here: the module
60 will be called me1400.
61
62config ME1600
63 tristate "Meilhaus ME-1600 support"
64 default n
65 depends on PCI
66 help
67 This driver supports the Meilhaus ME-1600 family of boards
68 that do data collection and multipurpose I/O.
69
70 To compile this driver as a module, choose M here: the module
71 will be called me1600.
72
73config ME4600
74 tristate "Meilhaus ME-4600 support"
75 default n
76 depends on PCI
77 help
78 This driver supports the Meilhaus ME-4600 family of boards
79 that do data collection and multipurpose I/O.
80
81 To compile this driver as a module, choose M here: the module
82 will be called me4600.
83
84config ME6000
85 tristate "Meilhaus ME-6000 support"
86 default n
87 depends on PCI
88 help
89 This driver supports the Meilhaus ME-6000 family of boards
90 that do data collection and multipurpose I/O.
91
92 To compile this driver as a module, choose M here: the module
93 will be called me6000.
94
95config ME8100
96 tristate "Meilhaus ME-8100 support"
97 default n
98 depends on PCI
99 help
100 This driver supports the Meilhaus ME-8100 family of boards
101 that do data collection and multipurpose I/O.
102
103 To compile this driver as a module, choose M here: the module
104 will be called me8100.
105
106config ME8200
107 tristate "Meilhaus ME-8200 support"
108 default n
109 depends on PCI
110 help
111 This driver supports the Meilhaus ME-8200 family of boards
112 that do data collection and multipurpose I/O.
113
114 To compile this driver as a module, choose M here: the module
115 will be called me8200.
116
117config MEDUMMY
118 tristate "Meilhaus dummy driver"
119 default n
120 depends on PCI
121 help
122 This provides a dummy driver for the Meilhaus driver package
123
124 To compile this driver as a module, choose M here: the module
125 will be called medummy.
126
127endif # MEILHAUS
diff --git a/drivers/staging/meilhaus/Makefile b/drivers/staging/meilhaus/Makefile
new file mode 100644
index 000000000000..5ab2c1c9c861
--- /dev/null
+++ b/drivers/staging/meilhaus/Makefile
@@ -0,0 +1,43 @@
1#
2# Makefile for Meilhaus linux driver system
3#
4
5obj-$(CONFIG_MEILHAUS) += memain.o
6obj-$(CONFIG_ME1600) += me1600.o
7obj-$(CONFIG_ME1000) += me1000.o
8obj-$(CONFIG_ME1400) += me1400.o
9obj-$(CONFIG_ME4600) += me4600.o
10obj-$(CONFIG_ME6000) += me6000.o
11obj-$(CONFIG_ME0600) += me0600.o
12obj-$(CONFIG_ME8100) += me8100.o
13obj-$(CONFIG_ME8200) += me8200.o
14obj-$(CONFIG_ME0900) += me0900.o
15obj-$(CONFIG_MEDUMMY) += medummy.o
16
17
18me1600-objs := medevice.o medlist.o medlock.o me1600_device.o
19me1600-objs += mesubdevice.o meslist.o meslock.o me1600_ao.o
20
21me1000-objs := medevice.o medlist.o medlock.o me1000_device.o
22me1000-objs += mesubdevice.o meslist.o meslock.o me1000_dio.o
23
24me1400-objs := medevice.o medlist.o medlock.o me1400_device.o
25me1400-objs += mesubdevice.o meslist.o meslock.o me8254.o me8255.o me1400_ext_irq.o
26
27me4600-objs := medevice.o medlist.o medlock.o mefirmware.o me4600_device.o
28me4600-objs += mesubdevice.o meslist.o meslock.o me4600_do.o me4600_di.o me4600_dio.o me8254.o me4600_ai.o me4600_ao.o me4600_ext_irq.o
29
30me6000-objs := medevice.o medlist.o medlock.o mefirmware.o me6000_device.o
31me6000-objs += mesubdevice.o meslist.o meslock.o me6000_dio.o me6000_ao.o
32
33me0600-objs := medevice.o medlist.o medlock.o me0600_device.o
34me0600-objs += mesubdevice.o meslist.o meslock.o me0600_relay.o me0600_ttli.o me0600_optoi.o me0600_dio.o me0600_ext_irq.o
35
36me8100-objs := medevice.o medlist.o medlock.o me8100_device.o
37me8100-objs += mesubdevice.o meslist.o meslock.o me8100_di.o me8100_do.o me8254.o
38
39me8200-objs := medevice.o medlist.o medlock.o me8200_device.o
40me8200-objs += mesubdevice.o meslist.o meslock.o me8200_di.o me8200_do.o me8200_dio.o
41
42me0900-objs := medevice.o medlist.o medlock.o me0900_device.o
43me0900-objs += mesubdevice.o meslist.o meslock.o me0900_do.o me0900_di.o
diff --git a/drivers/staging/meilhaus/TODO b/drivers/staging/meilhaus/TODO
new file mode 100644
index 000000000000..6ec25203089c
--- /dev/null
+++ b/drivers/staging/meilhaus/TODO
@@ -0,0 +1,10 @@
1TODO:
2 - checkpatch.pl cleanups
3 - sparse issues
4 - Lindent
5 - audit userspace interface
6 - handle firmware properly
7 - possible comedi merge
8
9Please send cleanup patches to Greg Kroah-Hartman <greg@kroah.com>
10and CC: David Kiliani <mail@davidkiliani.de>
diff --git a/drivers/staging/meilhaus/me0600_device.c b/drivers/staging/meilhaus/me0600_device.c
new file mode 100644
index 000000000000..8950e47e0e86
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_device.c
@@ -0,0 +1,215 @@
1/**
2 * @file me0600_device.c
3 *
4 * @brief ME-630 device class implementation.
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#ifndef MODULE
33# define MODULE
34#endif
35
36#include <linux/module.h>
37
38#include <linux/pci.h>
39#include <linux/slab.h>
40
41#include "meids.h"
42#include "meerror.h"
43#include "mecommon.h"
44#include "meinternal.h"
45
46#include "medebug.h"
47#include "medevice.h"
48#include "me0600_device.h"
49#include "mesubdevice.h"
50#include "me0600_relay.h"
51#include "me0600_ttli.h"
52#include "me0600_optoi.h"
53#include "me0600_dio.h"
54#include "me0600_ext_irq.h"
55
56me_device_t *me0600_pci_constructor(struct pci_dev *pci_device)
57{
58 me0600_device_t *me0600_device;
59 me_subdevice_t *subdevice;
60 unsigned int version_idx;
61 int err;
62 int i;
63
64 PDEBUG("executed.\n");
65
66 // Allocate structure for device instance.
67 me0600_device = kmalloc(sizeof(me0600_device_t), GFP_KERNEL);
68
69 if (!me0600_device) {
70 PERROR("Cannot get memory for device instance.\n");
71 return NULL;
72 }
73
74 memset(me0600_device, 0, sizeof(me0600_device_t));
75
76 // Initialize base class structure.
77 err = me_device_pci_init((me_device_t *) me0600_device, pci_device);
78
79 if (err) {
80 kfree(me0600_device);
81 PERROR("Cannot initialize device base class.\n");
82 return NULL;
83 }
84
85 /* Get the index in the device version information table. */
86 version_idx =
87 me0600_versions_get_device_index(me0600_device->base.info.pci.
88 device_id);
89
90 // Initialize spin lock .
91 spin_lock_init(&me0600_device->dio_ctrl_reg_lock);
92 spin_lock_init(&me0600_device->intcsr_lock);
93
94 // Create subdevice instances.
95
96 for (i = 0; i < me0600_versions[version_idx].optoi_subdevices; i++) {
97 subdevice =
98 (me_subdevice_t *) me0600_optoi_constructor(me0600_device->
99 base.info.pci.
100 reg_bases[2]);
101
102 if (!subdevice) {
103 me_device_deinit((me_device_t *) me0600_device);
104 kfree(me0600_device);
105 PERROR("Cannot get memory for subdevice.\n");
106 return NULL;
107 }
108
109 me_slist_add_subdevice_tail(&me0600_device->base.slist,
110 subdevice);
111 }
112
113 for (i = 0; i < me0600_versions[version_idx].relay_subdevices; i++) {
114 subdevice =
115 (me_subdevice_t *) me0600_relay_constructor(me0600_device->
116 base.info.pci.
117 reg_bases[2]);
118
119 if (!subdevice) {
120 me_device_deinit((me_device_t *) me0600_device);
121 kfree(me0600_device);
122 PERROR("Cannot get memory for subdevice.\n");
123 return NULL;
124 }
125
126 me_slist_add_subdevice_tail(&me0600_device->base.slist,
127 subdevice);
128 }
129
130 for (i = 0; i < me0600_versions[version_idx].ttli_subdevices; i++) {
131 subdevice =
132 (me_subdevice_t *) me0600_ttli_constructor(me0600_device->
133 base.info.pci.
134 reg_bases[2]);
135
136 if (!subdevice) {
137 me_device_deinit((me_device_t *) me0600_device);
138 kfree(me0600_device);
139 PERROR("Cannot get memory for subdevice.\n");
140 return NULL;
141 }
142
143 me_slist_add_subdevice_tail(&me0600_device->base.slist,
144 subdevice);
145 }
146
147 for (i = 0; i < me0600_versions[version_idx].dio_subdevices; i++) {
148 subdevice =
149 (me_subdevice_t *) me0600_dio_constructor(me0600_device->
150 base.info.pci.
151 reg_bases[2], i,
152 &me0600_device->
153 dio_ctrl_reg_lock);
154
155 if (!subdevice) {
156 me_device_deinit((me_device_t *) me0600_device);
157 kfree(me0600_device);
158 PERROR("Cannot get memory for subdevice.\n");
159 return NULL;
160 }
161
162 me_slist_add_subdevice_tail(&me0600_device->base.slist,
163 subdevice);
164 }
165
166 for (i = 0; i < me0600_versions[version_idx].ext_irq_subdevices; i++) {
167 subdevice =
168 (me_subdevice_t *)
169 me0600_ext_irq_constructor(me0600_device->base.info.pci.
170 reg_bases[1],
171 me0600_device->base.info.pci.
172 reg_bases[2],
173 &me0600_device->intcsr_lock, i,
174 me0600_device->base.irq);
175
176 if (!subdevice) {
177 me_device_deinit((me_device_t *) me0600_device);
178 kfree(me0600_device);
179 PERROR("Cannot get memory for subdevice.\n");
180 return NULL;
181 }
182
183 me_slist_add_subdevice_tail(&me0600_device->base.slist,
184 subdevice);
185 }
186
187 return (me_device_t *) me0600_device;
188}
189
190// Init and exit of module.
191
192static int __init me0600_init(void)
193{
194 PDEBUG("executed.\n");
195 return 0;
196}
197
198static void __exit me0600_exit(void)
199{
200 PDEBUG("executed.\n");
201}
202
203module_init(me0600_init);
204
205module_exit(me0600_exit);
206
207// Administrative stuff for modinfo.
208MODULE_AUTHOR
209 ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
210MODULE_DESCRIPTION("Device Driver Module for ME-6xx Device");
211MODULE_SUPPORTED_DEVICE("Meilhaus ME-6xx Devices");
212MODULE_LICENSE("GPL");
213
214// Export the constructor.
215EXPORT_SYMBOL(me0600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me0600_device.h b/drivers/staging/meilhaus/me0600_device.h
new file mode 100644
index 000000000000..d93a8aee581b
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_device.h
@@ -0,0 +1,97 @@
1/**
2 * @file me0600_device.h
3 *
4 * @brief ME-630 device class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0600_DEVICE_H
28#define _ME0600_DEVICE_H
29
30#include <linux/pci.h>
31#include <linux/spinlock.h>
32
33#include "medevice.h"
34
35#ifdef __KERNEL__
36
37/**
38 * @brief Structure holding ME-630 device capabilities.
39 */
40typedef struct me0600_version {
41 uint16_t device_id;
42 unsigned int relay_subdevices;
43 unsigned int ttli_subdevices;
44 unsigned int optoi_subdevices;
45 unsigned int dio_subdevices;
46 unsigned int ext_irq_subdevices;
47} me0600_version_t;
48
49/**
50 * @brief Device capabilities.
51 */
52static me0600_version_t me0600_versions[] = {
53 {PCI_DEVICE_ID_MEILHAUS_ME0630, 1, 1, 1, 2, 2},
54 {0},
55};
56
57#define ME0600_DEVICE_VERSIONS (sizeof(me0600_versions) / sizeof(me0600_version_t) - 1) /**< Returns the number of entries in #me0600_versions. */
58
59/**
60 * @brief Returns the index of the device entry in #me0600_versions.
61 *
62 * @param device_id The PCI device id of the device to query.
63 * @return The index of the device in #me0600_versions.
64 */
65static inline unsigned int me0600_versions_get_device_index(uint16_t device_id)
66{
67 unsigned int i;
68 for (i = 0; i < ME0600_DEVICE_VERSIONS; i++)
69 if (me0600_versions[i].device_id == device_id)
70 break;
71 return i;
72}
73
74/**
75 * @brief The ME-630 device class structure.
76 */
77typedef struct me0600_device {
78 me_device_t base; /**< The Meilhaus device base class. */
79
80 /* Child class attributes. */
81 spinlock_t dio_ctrl_reg_lock;
82 spinlock_t intcsr_lock;
83} me0600_device_t;
84
85/**
86 * @brief The ME-630 device class constructor.
87 *
88 * @param pci_device The pci device structure given by the PCI subsystem.
89 *
90 * @return On succes a new ME-630 device instance. \n
91 * NULL on error.
92 */
93me_device_t *me0600_pci_constructor(struct pci_dev *pci_device)
94 __attribute__ ((weak));
95
96#endif
97#endif
diff --git a/drivers/staging/meilhaus/me0600_dio.c b/drivers/staging/meilhaus/me0600_dio.c
new file mode 100644
index 000000000000..3a2775749a2c
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_dio.c
@@ -0,0 +1,415 @@
1/**
2 * @file me0600_dio.c
3 *
4 * @brief ME-630 digital input/output 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45
46#include "medebug.h"
47#include "me0600_dio_reg.h"
48#include "me0600_dio.h"
49
50/*
51 * Defines
52 */
53
54/*
55 * Functions
56 */
57
58static int me0600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
59 struct file *filep, int flags)
60{
61 me0600_dio_subdevice_t *instance;
62 uint8_t mode;
63
64 PDEBUG("executed.\n");
65
66 instance = (me0600_dio_subdevice_t *) subdevice;
67
68 if (flags) {
69 PERROR("Invalid flag specified.\n");
70 return ME_ERRNO_INVALID_FLAGS;
71 }
72
73 ME_SUBDEVICE_ENTER;
74
75 spin_lock(&instance->subdevice_lock);
76 spin_lock(instance->ctrl_reg_lock);
77 mode = inb(instance->ctrl_reg);
78 mode &= ~(0x3 << (instance->dio_idx * 2));
79 outb(mode, instance->ctrl_reg);
80 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
81 instance->ctrl_reg - instance->reg_base, mode);
82 spin_unlock(instance->ctrl_reg_lock);
83
84 outb(0x00, instance->port_reg);
85 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
86 instance->port_reg - instance->reg_base, 0x00);
87 spin_unlock(&instance->subdevice_lock);
88
89 ME_SUBDEVICE_EXIT;
90
91 return ME_ERRNO_SUCCESS;
92}
93
94static int me0600_dio_io_single_config(me_subdevice_t * subdevice,
95 struct file *filep,
96 int channel,
97 int single_config,
98 int ref,
99 int trig_chan,
100 int trig_type, int trig_edge, int flags)
101{
102 me0600_dio_subdevice_t *instance;
103 int err = ME_ERRNO_SUCCESS;
104 uint8_t mode;
105 int size =
106 flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
107 | ME_IO_SINGLE_CONFIG_DIO_WORD |
108 ME_IO_SINGLE_CONFIG_DIO_DWORD);
109
110 PDEBUG("executed.\n");
111
112 instance = (me0600_dio_subdevice_t *) subdevice;
113
114 ME_SUBDEVICE_ENTER;
115
116 spin_lock(&instance->subdevice_lock);
117 spin_lock(instance->ctrl_reg_lock);
118 mode = inb(instance->ctrl_reg);
119 switch (size) {
120 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
121 case ME_IO_SINGLE_CONFIG_DIO_BYTE:
122 if (channel == 0) {
123 if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
124 mode &=
125 ~((ME0600_DIO_CONFIG_BIT_OUT_0) <<
126 (instance->dio_idx * 2));
127 } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
128 mode &=
129 ~((ME0600_DIO_CONFIG_BIT_OUT_0) <<
130 (instance->dio_idx * 2));
131 mode |=
132 ME0600_DIO_CONFIG_BIT_OUT_0 << (instance->
133 dio_idx *
134 2);
135 } else {
136 PERROR
137 ("Invalid port configuration specified.\n");
138 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
139 }
140 } else {
141 PERROR("Invalid channel number.\n");
142 err = ME_ERRNO_INVALID_CHANNEL;
143 }
144 break;
145
146 default:
147 PERROR("Invalid flags.\n");
148 err = ME_ERRNO_INVALID_FLAGS;
149 }
150
151 if (!err) {
152 outb(mode, instance->ctrl_reg);
153 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
154 instance->reg_base,
155 instance->ctrl_reg - instance->reg_base, mode);
156 }
157 spin_unlock(instance->ctrl_reg_lock);
158 spin_unlock(&instance->subdevice_lock);
159
160 ME_SUBDEVICE_EXIT;
161
162 return err;
163}
164
165static int me0600_dio_io_single_read(me_subdevice_t * subdevice,
166 struct file *filep,
167 int channel,
168 int *value, int time_out, int flags)
169{
170 me0600_dio_subdevice_t *instance;
171 int err = ME_ERRNO_SUCCESS;
172 uint8_t mode;
173
174 PDEBUG("executed.\n");
175
176 instance = (me0600_dio_subdevice_t *) subdevice;
177
178 ME_SUBDEVICE_ENTER;
179
180 spin_lock(&instance->subdevice_lock);
181 spin_lock(instance->ctrl_reg_lock);
182 switch (flags) {
183 case ME_IO_SINGLE_TYPE_DIO_BIT:
184 if ((channel >= 0) && (channel < 8)) {
185 mode =
186 inb(instance->
187 ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
188 (instance->dio_idx * 2));
189
190 if ((mode ==
191 (ME0600_DIO_CONFIG_BIT_OUT_0 <<
192 (instance->dio_idx * 2))) || !mode) {
193 *value =
194 inb(instance->
195 port_reg) & (0x0001 << channel);
196 } else {
197 PERROR("Port not in output or input mode.\n");
198 err = ME_ERRNO_PREVIOUS_CONFIG;
199 }
200 } else {
201 PERROR("Invalid bit number specified.\n");
202 err = ME_ERRNO_INVALID_CHANNEL;
203 }
204
205 break;
206
207 case ME_IO_SINGLE_NO_FLAGS:
208 case ME_IO_SINGLE_TYPE_DIO_BYTE:
209 if (channel == 0) {
210 mode =
211 inb(instance->
212 ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
213 (instance->dio_idx * 2));
214
215 if ((mode ==
216 (ME0600_DIO_CONFIG_BIT_OUT_0 <<
217 (instance->dio_idx * 2))) || !mode) {
218 *value = inb(instance->port_reg) & 0x00FF;
219 } else {
220 PERROR("Port not in output or input mode.\n");
221 err = ME_ERRNO_PREVIOUS_CONFIG;
222 }
223 } else {
224 PERROR("Invalid byte number specified.\n");
225 err = ME_ERRNO_INVALID_CHANNEL;
226 }
227
228 break;
229
230 default:
231 PERROR("Invalid flags specified.\n");
232
233 err = ME_ERRNO_INVALID_FLAGS;
234
235 break;
236 }
237 spin_unlock(instance->ctrl_reg_lock);
238 spin_unlock(&instance->subdevice_lock);
239
240 ME_SUBDEVICE_EXIT;
241
242 return err;
243}
244
245static int me0600_dio_io_single_write(me_subdevice_t * subdevice,
246 struct file *filep,
247 int channel,
248 int value, int time_out, int flags)
249{
250 me0600_dio_subdevice_t *instance;
251 int err = ME_ERRNO_SUCCESS;
252 uint8_t mode;
253 uint8_t byte;
254
255 PDEBUG("executed.\n");
256
257 instance = (me0600_dio_subdevice_t *) subdevice;
258
259 ME_SUBDEVICE_ENTER;
260
261 spin_lock(&instance->subdevice_lock);
262 spin_lock(instance->ctrl_reg_lock);
263 switch (flags) {
264
265 case ME_IO_SINGLE_TYPE_DIO_BIT:
266 if ((channel >= 0) && (channel < 8)) {
267 mode =
268 inb(instance->
269 ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
270 (instance->dio_idx * 2));
271
272 if (mode ==
273 (ME0600_DIO_CONFIG_BIT_OUT_0 <<
274 (instance->dio_idx * 2))) {
275 byte = inb(instance->port_reg);
276
277 if (value)
278 byte |= 0x1 << channel;
279 else
280 byte &= ~(0x1 << channel);
281
282 outb(byte, instance->port_reg);
283 } else {
284 PERROR("Port not in output or input mode.\n");
285 err = ME_ERRNO_PREVIOUS_CONFIG;
286 }
287 } else {
288 PERROR("Invalid bit number specified.\n");
289 err = ME_ERRNO_INVALID_CHANNEL;
290 }
291
292 break;
293
294 case ME_IO_SINGLE_NO_FLAGS:
295 case ME_IO_SINGLE_TYPE_DIO_BYTE:
296 if (channel == 0) {
297 mode =
298 inb(instance->
299 ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
300 (instance->dio_idx * 2));
301
302 if (mode ==
303 (ME0600_DIO_CONFIG_BIT_OUT_0 <<
304 (instance->dio_idx * 2))) {
305 outb(value, instance->port_reg);
306 } else {
307 PERROR("Port not in output or input mode.\n");
308 err = ME_ERRNO_PREVIOUS_CONFIG;
309 }
310 } else {
311 PERROR("Invalid byte number specified.\n");
312 err = ME_ERRNO_INVALID_CHANNEL;
313 }
314
315 break;
316
317 default:
318 PERROR("Invalid flags specified.\n");
319
320 err = ME_ERRNO_INVALID_FLAGS;
321
322 break;
323 }
324 spin_unlock(instance->ctrl_reg_lock);
325 spin_unlock(&instance->subdevice_lock);
326
327 ME_SUBDEVICE_EXIT;
328
329 return err;
330}
331
332static int me0600_dio_query_number_channels(me_subdevice_t * subdevice,
333 int *number)
334{
335 PDEBUG("executed.\n");
336 *number = 8;
337 return ME_ERRNO_SUCCESS;
338}
339
340static int me0600_dio_query_subdevice_type(me_subdevice_t * subdevice,
341 int *type, int *subtype)
342{
343 PDEBUG("executed.\n");
344 *type = ME_TYPE_DIO;
345 *subtype = ME_SUBTYPE_SINGLE;
346 return ME_ERRNO_SUCCESS;
347}
348
349static int me0600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
350 int *caps)
351{
352 PDEBUG("executed.\n");
353 *caps = ME_CAPS_DIO_DIR_BYTE;
354 return ME_ERRNO_SUCCESS;
355}
356
357me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
358 unsigned int dio_idx,
359 spinlock_t * ctrl_reg_lock)
360{
361 me0600_dio_subdevice_t *subdevice;
362 int err;
363
364 PDEBUG("executed.\n");
365
366 /* Allocate memory for subdevice instance */
367 subdevice = kmalloc(sizeof(me0600_dio_subdevice_t), GFP_KERNEL);
368
369 if (!subdevice) {
370 PERROR("Cannot get memory for subdevice instance.\n");
371 return NULL;
372 }
373
374 memset(subdevice, 0, sizeof(me0600_dio_subdevice_t));
375
376 /* Initialize subdevice base class */
377 err = me_subdevice_init(&subdevice->base);
378
379 if (err) {
380 PERROR("Cannot initialize subdevice base class instance.\n");
381 kfree(subdevice);
382 return NULL;
383 }
384 // Initialize spin locks.
385 spin_lock_init(&subdevice->subdevice_lock);
386
387 subdevice->ctrl_reg_lock = ctrl_reg_lock;
388
389 /* Save digital i/o index */
390 subdevice->dio_idx = dio_idx;
391
392 /* Save the subdevice index */
393 subdevice->ctrl_reg = reg_base + ME0600_DIO_CONFIG_REG;
394 subdevice->port_reg = reg_base + ME0600_DIO_PORT_REG + dio_idx;
395#ifdef MEDEBUG_DEBUG_REG
396 subdevice->reg_base = reg_base;
397#endif
398
399 /* Overload base class methods. */
400 subdevice->base.me_subdevice_io_reset_subdevice =
401 me0600_dio_io_reset_subdevice;
402 subdevice->base.me_subdevice_io_single_config =
403 me0600_dio_io_single_config;
404 subdevice->base.me_subdevice_io_single_read = me0600_dio_io_single_read;
405 subdevice->base.me_subdevice_io_single_write =
406 me0600_dio_io_single_write;
407 subdevice->base.me_subdevice_query_number_channels =
408 me0600_dio_query_number_channels;
409 subdevice->base.me_subdevice_query_subdevice_type =
410 me0600_dio_query_subdevice_type;
411 subdevice->base.me_subdevice_query_subdevice_caps =
412 me0600_dio_query_subdevice_caps;
413
414 return subdevice;
415}
diff --git a/drivers/staging/meilhaus/me0600_dio.h b/drivers/staging/meilhaus/me0600_dio.h
new file mode 100644
index 000000000000..5d075c7d6882
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_dio.h
@@ -0,0 +1,68 @@
1/**
2 * @file me0600_dio.h
3 *
4 * @brief ME-630 digital input/output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0600_DIO_H_
28#define _ME0600_DIO_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me0600_dio_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
44 unsigned int dio_idx; /**< The index of the digital i/o on the device. */
45
46 unsigned long port_reg; /**< Register holding the port status. */
47 unsigned long ctrl_reg; /**< Register to configure the port direction. */
48#ifdef MEDEBUG_DEBUG_REG
49 unsigned long reg_base;
50#endif
51} me0600_dio_subdevice_t;
52
53/**
54 * @brief The constructor to generate a ME-630 digital input/ouput subdevice instance.
55 *
56 * @param reg_base The register base address of the device as returned by the PCI BIOS.
57 * @param dio_idx The index of the digital i/o port on the device.
58 * @param ctrl_reg_lock Spin lock protecting the control register.
59 *
60 * @return Pointer to new instance on success.\n
61 * NULL on error.
62 */
63me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
64 unsigned int dio_idx,
65 spinlock_t * ctrl_reg_lock);
66
67#endif
68#endif
diff --git a/drivers/staging/meilhaus/me0600_dio_reg.h b/drivers/staging/meilhaus/me0600_dio_reg.h
new file mode 100644
index 000000000000..f116ea3b79d2
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_dio_reg.h
@@ -0,0 +1,41 @@
1/**
2 * @file me0600_dio_reg.h
3 *
4 * @brief ME-630 digital input/output subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0600_DIO_REG_H_
28#define _ME0600_DIO_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME0600_DIO_CONFIG_REG 0x0007
33#define ME0600_DIO_PORT_0_REG 0x0008
34#define ME0600_DIO_PORT_1_REG 0x0009
35#define ME0600_DIO_PORT_REG ME0600_DIO_PORT_0_REG
36
37#define ME0600_DIO_CONFIG_BIT_OUT_0 0x0001
38#define ME0600_DIO_CONFIG_BIT_OUT_1 0x0004
39
40#endif
41#endif
diff --git a/drivers/staging/meilhaus/me0600_ext_irq.c b/drivers/staging/meilhaus/me0600_ext_irq.c
new file mode 100644
index 000000000000..a449ab200940
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_ext_irq.c
@@ -0,0 +1,478 @@
1/**
2 * @file me0600_ext_irq.c
3 *
4 * @brief ME-630 external interrupt 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/version.h>
36#include <linux/module.h>
37
38#include <linux/slab.h>
39#include <linux/spinlock.h>
40#include <asm/io.h>
41#include <linux/types.h>
42#include <linux/interrupt.h>
43
44#include "medefines.h"
45#include "meinternal.h"
46#include "meerror.h"
47#include "meids.h"
48#include "medebug.h"
49
50#include "meplx_reg.h"
51#include "me0600_ext_irq_reg.h"
52#include "me0600_ext_irq.h"
53
54/*
55 * Functions
56 */
57
58static int me0600_ext_irq_io_irq_start(struct me_subdevice *subdevice,
59 struct file *filep,
60 int channel,
61 int irq_source,
62 int irq_edge, int irq_arg, int flags)
63{
64 me0600_ext_irq_subdevice_t *instance;
65 uint32_t tmp;
66 unsigned long cpu_flags;
67
68 PDEBUG("executed.\n");
69
70 instance = (me0600_ext_irq_subdevice_t *) subdevice;
71
72 if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
73 PERROR("Invalid flag specified.\n");
74 return ME_ERRNO_INVALID_FLAGS;
75 }
76
77 if (instance->lintno > 1) {
78 PERROR("Wrong idx=%d.\n", instance->lintno);
79 return ME_ERRNO_INVALID_SUBDEVICE;
80 }
81
82 if (channel) {
83 PERROR("Invalid channel specified.\n");
84 return ME_ERRNO_INVALID_CHANNEL;
85 }
86
87 if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
88 PERROR("Invalid irq source specified.\n");
89 return ME_ERRNO_INVALID_IRQ_SOURCE;
90 }
91
92 if (irq_edge != ME_IRQ_EDGE_RISING) {
93 PERROR("Invalid irq edge specified.\n");
94 return ME_ERRNO_INVALID_IRQ_EDGE;
95 }
96
97 ME_SUBDEVICE_ENTER;
98
99 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
100 spin_lock(instance->intcsr_lock);
101 tmp = inl(instance->intcsr);
102 switch (instance->lintno) {
103 case 0:
104 tmp |=
105 PLX_INTCSR_LOCAL_INT1_EN | PLX_INTCSR_LOCAL_INT1_POL |
106 PLX_INTCSR_PCI_INT_EN;
107 break;
108 case 1:
109 tmp |=
110 PLX_INTCSR_LOCAL_INT2_EN | PLX_INTCSR_LOCAL_INT2_POL |
111 PLX_INTCSR_PCI_INT_EN;
112 break;
113 }
114 outl(tmp, instance->intcsr);
115 PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp);
116 spin_unlock(instance->intcsr_lock);
117 instance->rised = 0;
118 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
119
120 ME_SUBDEVICE_EXIT;
121
122 return ME_ERRNO_SUCCESS;
123}
124
125static int me0600_ext_irq_io_irq_wait(struct me_subdevice *subdevice,
126 struct file *filep,
127 int channel,
128 int *irq_count,
129 int *value, int time_out, int flags)
130{
131 me0600_ext_irq_subdevice_t *instance;
132 int err = ME_ERRNO_SUCCESS;
133 long t = 0;
134 unsigned long cpu_flags;
135
136 PDEBUG("executed.\n");
137
138 instance = (me0600_ext_irq_subdevice_t *) subdevice;
139
140 if (flags) {
141 PERROR("Invalid flag specified.\n");
142 return ME_ERRNO_INVALID_FLAGS;
143 }
144
145 if (channel) {
146 PERROR("Invalid channel specified.\n");
147 return ME_ERRNO_INVALID_CHANNEL;
148 }
149
150 if (time_out < 0) {
151 PERROR("Invalid time_out specified.\n");
152 return ME_ERRNO_INVALID_TIMEOUT;
153 }
154
155 if (time_out) {
156 t = (time_out * HZ) / 1000;
157
158 if (t == 0)
159 t = 1;
160 }
161
162 ME_SUBDEVICE_ENTER;
163
164 if (instance->rised <= 0) {
165 instance->rised = 0;
166
167 if (time_out) {
168 t = wait_event_interruptible_timeout(instance->
169 wait_queue,
170 (instance->rised !=
171 0), t);
172
173 if (t == 0) {
174 PERROR("Wait on interrupt timed out.\n");
175 err = ME_ERRNO_TIMEOUT;
176 }
177 } else {
178 wait_event_interruptible(instance->wait_queue,
179 (instance->rised != 0));
180 }
181
182 if (instance->rised < 0) {
183 PERROR("Wait on interrupt aborted by user.\n");
184 err = ME_ERRNO_CANCELLED;
185 }
186 }
187
188 if (signal_pending(current)) {
189 PERROR("Wait on interrupt aborted by signal.\n");
190 err = ME_ERRNO_SIGNAL;
191 }
192
193 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
194 instance->rised = 0;
195 *irq_count = instance->n;
196 *value = 1;
197 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
198
199 ME_SUBDEVICE_EXIT;
200
201 return err;
202}
203
204static int me0600_ext_irq_io_irq_stop(struct me_subdevice *subdevice,
205 struct file *filep,
206 int channel, int flags)
207{
208 me0600_ext_irq_subdevice_t *instance;
209 int err = ME_ERRNO_SUCCESS;
210 uint32_t tmp;
211 unsigned long cpu_flags;
212
213 PDEBUG("executed.\n");
214
215 instance = (me0600_ext_irq_subdevice_t *) subdevice;
216
217 if (flags) {
218 PERROR("Invalid flag specified.\n");
219 return ME_ERRNO_INVALID_FLAGS;
220 }
221
222 if (instance->lintno > 1) {
223 PERROR("Wrong idx=%d.\n", instance->lintno);
224 return ME_ERRNO_INVALID_SUBDEVICE;
225 }
226
227 if (channel) {
228 PERROR("Invalid channel specified.\n");
229 return ME_ERRNO_INVALID_CHANNEL;
230 }
231
232 ME_SUBDEVICE_ENTER;
233
234 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
235 spin_lock(instance->intcsr_lock);
236 tmp = inl(instance->intcsr);
237 switch (instance->lintno) {
238 case 0:
239 tmp &= ~PLX_INTCSR_LOCAL_INT1_EN;
240 break;
241 case 1:
242 tmp &= ~PLX_INTCSR_LOCAL_INT2_EN;
243 break;
244 }
245 outl(tmp, instance->intcsr);
246 PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp);
247 spin_unlock(instance->intcsr_lock);
248 instance->rised = -1;
249 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
250 wake_up_interruptible_all(&instance->wait_queue);
251
252 ME_SUBDEVICE_EXIT;
253
254 return err;
255}
256
257static int me0600_ext_irq_io_reset_subdevice(struct me_subdevice *subdevice,
258 struct file *filep, int flags)
259{
260 me0600_ext_irq_subdevice_t *instance;
261 uint32_t tmp;
262 unsigned long cpu_flags;
263
264 PDEBUG("executed.\n");
265
266 instance = (me0600_ext_irq_subdevice_t *) subdevice;
267
268 if (flags) {
269 PERROR("Invalid flag specified.\n");
270 return ME_ERRNO_INVALID_FLAGS;
271 }
272
273 ME_SUBDEVICE_ENTER;
274
275 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
276 spin_lock(instance->intcsr_lock);
277 tmp = inl(instance->intcsr);
278 switch (instance->lintno) {
279 case 0:
280 tmp |= PLX_INTCSR_LOCAL_INT1_POL | PLX_INTCSR_PCI_INT_EN;
281 tmp &= ~PLX_INTCSR_LOCAL_INT1_EN;
282 break;
283 case 1:
284 tmp |= PLX_INTCSR_LOCAL_INT2_POL | PLX_INTCSR_PCI_INT_EN;
285 tmp &= ~PLX_INTCSR_LOCAL_INT2_EN;
286 break;
287 }
288 outl(tmp, instance->intcsr);
289 PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp);
290 spin_unlock(instance->intcsr_lock);
291
292 instance->rised = -1;
293 instance->n = 0;
294 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
295 wake_up_interruptible_all(&instance->wait_queue);
296
297 ME_SUBDEVICE_EXIT;
298
299 return ME_ERRNO_SUCCESS;
300}
301
302static int me0600_ext_irq_query_number_channels(struct me_subdevice *subdevice,
303 int *number)
304{
305 PDEBUG("executed.\n");
306 *number = 1;
307 return ME_ERRNO_SUCCESS;
308}
309
310static int me0600_ext_irq_query_subdevice_type(struct me_subdevice *subdevice,
311 int *type, int *subtype)
312{
313 PDEBUG("executed.\n");
314 *type = ME_TYPE_EXT_IRQ;
315 *subtype = ME_SUBTYPE_SINGLE;
316 return ME_ERRNO_SUCCESS;
317}
318
319static int me0600_ext_irq_query_subdevice_caps(struct me_subdevice *subdevice,
320 int *caps)
321{
322 PDEBUG("executed.\n");
323 *caps = ME_CAPS_EXT_IRQ_EDGE_RISING;
324 return ME_ERRNO_SUCCESS;
325}
326
327static void me0600_ext_irq_destructor(struct me_subdevice *subdevice)
328{
329 me0600_ext_irq_subdevice_t *instance;
330
331 PDEBUG("executed.\n");
332
333 instance = (me0600_ext_irq_subdevice_t *) subdevice;
334
335 free_irq(instance->irq, (void *)instance);
336 me_subdevice_deinit(&instance->base);
337 kfree(instance);
338}
339
340#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
341static irqreturn_t me0600_isr(int irq, void *dev_id)
342#else
343static irqreturn_t me0600_isr(int irq, void *dev_id, struct pt_regs *regs)
344#endif
345{
346 me0600_ext_irq_subdevice_t *instance;
347 uint32_t status;
348 uint32_t mask = PLX_INTCSR_PCI_INT_EN;
349 irqreturn_t ret = IRQ_HANDLED;
350
351 instance = (me0600_ext_irq_subdevice_t *) dev_id;
352
353 if (irq != instance->irq) {
354 PERROR("Incorrect interrupt num: %d.\n", irq);
355 return IRQ_NONE;
356 }
357
358 PDEBUG("executed.\n");
359
360 if (instance->lintno > 1) {
361 PERROR_CRITICAL
362 ("%s():Wrong subdevice index=%d plx:irq_status_reg=0x%04X.\n",
363 __FUNCTION__, instance->lintno, inl(instance->intcsr));
364 return IRQ_NONE;
365 }
366
367 spin_lock(&instance->subdevice_lock);
368 spin_lock(instance->intcsr_lock);
369 status = inl(instance->intcsr);
370 switch (instance->lintno) {
371 case 0:
372 mask |= PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_LOCAL_INT1_EN;
373 break;
374 case 1:
375 mask |= PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_LOCAL_INT2_EN;
376 break;
377 }
378
379 if ((status & mask) == mask) {
380 instance->rised = 1;
381 instance->n++;
382 inb(instance->reset_reg);
383 PDEBUG("Interrupt detected.\n");
384 } else {
385 PINFO
386 ("%ld Shared interrupt. %s(): idx=0 plx:irq_status_reg=0x%04X\n",
387 jiffies, __FUNCTION__, status);
388 ret = IRQ_NONE;
389 }
390 spin_unlock(instance->intcsr_lock);
391 spin_unlock(&instance->subdevice_lock);
392
393 wake_up_interruptible_all(&instance->wait_queue);
394
395 return ret;
396}
397
398me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base,
399 uint32_t me0600_reg_base,
400 spinlock_t * intcsr_lock,
401 unsigned ext_irq_idx,
402 int irq)
403{
404 me0600_ext_irq_subdevice_t *subdevice;
405 int err;
406
407 PDEBUG("executed.\n");
408
409 /* Allocate memory for subdevice instance */
410 subdevice = kmalloc(sizeof(me0600_ext_irq_subdevice_t), GFP_KERNEL);
411
412 if (!subdevice) {
413 PERROR("Cannot get memory for 630_ext_irq instance.\n");
414 return NULL;
415 }
416
417 memset(subdevice, 0, sizeof(me0600_ext_irq_subdevice_t));
418
419 /* Initialize subdevice base class */
420 err = me_subdevice_init(&subdevice->base);
421
422 if (err) {
423 PERROR("Cannot initialize subdevice base class instance.\n");
424 kfree(subdevice);
425 return NULL;
426 }
427 // Initialize spin locks.
428 spin_lock_init(&subdevice->subdevice_lock);
429
430 subdevice->intcsr_lock = intcsr_lock;
431
432 /* Initialize wait queue */
433 init_waitqueue_head(&subdevice->wait_queue);
434
435 subdevice->lintno = ext_irq_idx;
436
437 /* Request interrupt line */
438 subdevice->irq = irq;
439
440 err = request_irq(subdevice->irq, me0600_isr,
441#ifdef IRQF_DISABLED
442 IRQF_DISABLED | IRQF_SHARED,
443#else
444 SA_INTERRUPT | SA_SHIRQ,
445#endif
446 ME0600_NAME, (void *)subdevice);
447
448 if (err) {
449 PERROR("Cannot get interrupt line.\n");
450 kfree(subdevice);
451 return NULL;
452 }
453 PINFO("Registered irq=%d.\n", subdevice->irq);
454
455 /* Initialize registers */
456 subdevice->intcsr = plx_reg_base + PLX_INTCSR;
457 subdevice->reset_reg =
458 me0600_reg_base + ME0600_INT_0_RESET_REG + ext_irq_idx;
459
460 /* Initialize the subdevice methods */
461 subdevice->base.me_subdevice_io_irq_start = me0600_ext_irq_io_irq_start;
462 subdevice->base.me_subdevice_io_irq_wait = me0600_ext_irq_io_irq_wait;
463 subdevice->base.me_subdevice_io_irq_stop = me0600_ext_irq_io_irq_stop;
464 subdevice->base.me_subdevice_io_reset_subdevice =
465 me0600_ext_irq_io_reset_subdevice;
466 subdevice->base.me_subdevice_query_number_channels =
467 me0600_ext_irq_query_number_channels;
468 subdevice->base.me_subdevice_query_subdevice_type =
469 me0600_ext_irq_query_subdevice_type;
470 subdevice->base.me_subdevice_query_subdevice_caps =
471 me0600_ext_irq_query_subdevice_caps;
472 subdevice->base.me_subdevice_destructor = me0600_ext_irq_destructor;
473
474 subdevice->rised = 0;
475 subdevice->n = 0;
476
477 return subdevice;
478}
diff --git a/drivers/staging/meilhaus/me0600_ext_irq.h b/drivers/staging/meilhaus/me0600_ext_irq.h
new file mode 100644
index 000000000000..f5f2204b49a0
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_ext_irq.h
@@ -0,0 +1,58 @@
1/**
2 * @file me0600_ext_irq.h
3 *
4 * @brief ME-630 external interrupt implementation.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _ME0600_EXT_IRQ_H_
10#define _ME0600_EXT_IRQ_H_
11
12#include <linux/sched.h>
13
14#include "mesubdevice.h"
15#include "meslock.h"
16
17#ifdef __KERNEL__
18
19/**
20 * @brief The ME-630 external interrupt subdevice class.
21 */
22typedef struct me0600_ext_irq_subdevice {
23 /* Inheritance */
24 me_subdevice_t base; /**< The subdevice base class. */
25
26 /* Attributes */
27 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
28 spinlock_t *intcsr_lock; /**< Spin lock to protect #intcsr. */
29
30 wait_queue_head_t wait_queue; /**< Queue to put on threads waiting for an interrupt. */
31
32 int irq; /**< The irq number assigned by PCI BIOS. */
33 int rised; /**< If true an interrupt has occured. */
34 unsigned int n; /**< The number of interrupt since the driver was loaded. */
35 unsigned int lintno; /**< The number of the local PCI interrupt. */
36
37 uint32_t intcsr; /**< The PLX interrupt control and status register. */
38 uint32_t reset_reg; /**< The control register. */
39} me0600_ext_irq_subdevice_t;
40
41/**
42 * @brief The constructor to generate a ME-630 external interrupt instance.
43 *
44 * @param plx_reg_base The register base address of the PLX chip as returned by the PCI BIOS.
45 * @param me0600_reg_base The register base address of the ME-630 device as returned by the PCI BIOS.
46 * @param irq The irq assigned by the PCI BIOS.
47 *
48 * @return Pointer to new instance on success.\n
49 * NULL on error.
50 */
51me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base,
52 uint32_t me0600_reg_base,
53 spinlock_t * intcsr_lock,
54 unsigned int ext_irq_idx,
55 int irq);
56
57#endif
58#endif
diff --git a/drivers/staging/meilhaus/me0600_ext_irq_reg.h b/drivers/staging/meilhaus/me0600_ext_irq_reg.h
new file mode 100644
index 000000000000..f6198fa6d2b2
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_ext_irq_reg.h
@@ -0,0 +1,18 @@
1/**
2 * @file me0600_ext_irq_reg.h
3 *
4 * @brief ME-630 external interrupt register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _ME0600_EXT_IRQ_REG_H_
10#define _ME0600_EXT_IRQ_REG_H_
11
12#ifdef __KERNEL__
13
14#define ME0600_INT_0_RESET_REG 0x0005
15#define ME0600_INT_1_RESET_REG 0x0006
16
17#endif
18#endif
diff --git a/drivers/staging/meilhaus/me0600_optoi.c b/drivers/staging/meilhaus/me0600_optoi.c
new file mode 100644
index 000000000000..b6d977f228ca
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_optoi.c
@@ -0,0 +1,243 @@
1/**
2 * @file me0600_optoi.c
3 *
4 * @brief ME-630 Optoisolated 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45
46#include "medebug.h"
47#include "me0600_optoi_reg.h"
48#include "me0600_optoi.h"
49
50/*
51 * Defines
52 */
53
54/*
55 * Functions
56 */
57
58static int me0600_optoi_io_reset_subdevice(struct me_subdevice *subdevice,
59 struct file *filep, int flags)
60{
61
62 if (flags) {
63 PERROR("Invalid flag specified.\n");
64 return ME_ERRNO_INVALID_FLAGS;
65 }
66
67 PDEBUG("executed.\n");
68 return ME_ERRNO_SUCCESS;
69}
70
71static int me0600_optoi_io_single_config(me_subdevice_t * subdevice,
72 struct file *filep,
73 int channel,
74 int single_config,
75 int ref,
76 int trig_chan,
77 int trig_type,
78 int trig_edge, int flags)
79{
80 me0600_optoi_subdevice_t *instance;
81 int err = ME_ERRNO_SUCCESS;
82
83 PDEBUG("executed.\n");
84
85 instance = (me0600_optoi_subdevice_t *) subdevice;
86
87 ME_SUBDEVICE_ENTER;
88
89 spin_lock(&instance->subdevice_lock);
90
91 switch (flags) {
92 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
93 case ME_IO_SINGLE_CONFIG_DIO_BYTE:
94 if (channel == 0) {
95 if (single_config != ME_SINGLE_CONFIG_DIO_INPUT) {
96 PERROR("Invalid port direction specified.\n");
97 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
98 }
99 } else {
100 PERROR("Invalid channel specified.\n");
101 err = ME_ERRNO_INVALID_CHANNEL;
102 }
103
104 break;
105
106 default:
107 PERROR("Invalid flags specified.\n");
108
109 err = ME_ERRNO_INVALID_FLAGS;
110
111 break;
112 }
113
114 spin_unlock(&instance->subdevice_lock);
115
116 ME_SUBDEVICE_EXIT;
117
118 return err;
119}
120
121static int me0600_optoi_io_single_read(me_subdevice_t * subdevice,
122 struct file *filep,
123 int channel,
124 int *value, int time_out, int flags)
125{
126 me0600_optoi_subdevice_t *instance;
127 int err = ME_ERRNO_SUCCESS;
128
129 PDEBUG("executed.\n");
130
131 instance = (me0600_optoi_subdevice_t *) subdevice;
132
133 ME_SUBDEVICE_ENTER;
134
135 spin_lock(&instance->subdevice_lock);
136
137 switch (flags) {
138 case ME_IO_SINGLE_TYPE_DIO_BIT:
139 if ((channel >= 0) && (channel < 8)) {
140 *value = inb(instance->port_reg) & (0x1 << channel);
141 } else {
142 PERROR("Invalid bit number specified.\n");
143 err = ME_ERRNO_INVALID_CHANNEL;
144 }
145
146 break;
147
148 case ME_IO_SINGLE_NO_FLAGS:
149 case ME_IO_SINGLE_TYPE_DIO_BYTE:
150 if (channel == 0) {
151 *value = inb(instance->port_reg);
152 } else {
153 PERROR("Invalid byte number specified.\n");
154 err = ME_ERRNO_INVALID_CHANNEL;
155 }
156
157 break;
158
159 default:
160 PERROR("Invalid flags specified.\n");
161
162 err = ME_ERRNO_INVALID_FLAGS;
163 }
164
165 spin_unlock(&instance->subdevice_lock);
166
167 ME_SUBDEVICE_EXIT;
168
169 return err;
170}
171
172static int me0600_optoi_query_number_channels(me_subdevice_t * subdevice,
173 int *number)
174{
175 PDEBUG("executed.\n");
176 *number = 8;
177 return ME_ERRNO_SUCCESS;
178}
179
180static int me0600_optoi_query_subdevice_type(me_subdevice_t * subdevice,
181 int *type, int *subtype)
182{
183 PDEBUG("executed.\n");
184 *type = ME_TYPE_DI;
185 *subtype = ME_SUBTYPE_SINGLE;
186 return ME_ERRNO_SUCCESS;
187}
188
189static int me0600_optoi_query_subdevice_caps(me_subdevice_t * subdevice,
190 int *caps)
191{
192 PDEBUG("executed.\n");
193 *caps = 0;
194 return ME_ERRNO_SUCCESS;
195}
196
197me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base)
198{
199 me0600_optoi_subdevice_t *subdevice;
200 int err;
201
202 PDEBUG("executed.\n");
203
204 /* Allocate memory for subdevice instance */
205 subdevice = kmalloc(sizeof(me0600_optoi_subdevice_t), GFP_KERNEL);
206
207 if (!subdevice) {
208 PERROR("Cannot get memory for subdevice instance.\n");
209 return NULL;
210 }
211
212 memset(subdevice, 0, sizeof(me0600_optoi_subdevice_t));
213
214 /* Initialize subdevice base class */
215 err = me_subdevice_init(&subdevice->base);
216
217 if (err) {
218 PERROR("Cannot initialize subdevice base class instance.\n");
219 kfree(subdevice);
220 return NULL;
221 }
222 // Initialize spin locks.
223 spin_lock_init(&subdevice->subdevice_lock);
224
225 /* Save the subdevice index */
226 subdevice->port_reg = reg_base + ME0600_OPTO_INPUT_REG;
227
228 /* Overload base class methods. */
229 subdevice->base.me_subdevice_io_reset_subdevice =
230 me0600_optoi_io_reset_subdevice;
231 subdevice->base.me_subdevice_io_single_config =
232 me0600_optoi_io_single_config;
233 subdevice->base.me_subdevice_io_single_read =
234 me0600_optoi_io_single_read;
235 subdevice->base.me_subdevice_query_number_channels =
236 me0600_optoi_query_number_channels;
237 subdevice->base.me_subdevice_query_subdevice_type =
238 me0600_optoi_query_subdevice_type;
239 subdevice->base.me_subdevice_query_subdevice_caps =
240 me0600_optoi_query_subdevice_caps;
241
242 return subdevice;
243}
diff --git a/drivers/staging/meilhaus/me0600_optoi.h b/drivers/staging/meilhaus/me0600_optoi.h
new file mode 100644
index 000000000000..e7e69bcde9c9
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_optoi.h
@@ -0,0 +1,58 @@
1/**
2 * @file me0600_optoi.h
3 *
4 * @brief ME-630 Optoisolated input subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0600_OPTOI_H_
28#define _ME0600_OPTOI_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me0600_optoi_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43
44 uint32_t port_reg; /**< Register holding the port status. */
45} me0600_optoi_subdevice_t;
46
47/**
48 * @brief The constructor to generate a ME-630 Optoisolated input subdevice instance.
49 *
50 * @param reg_base The register base address of the device as returned by the PCI BIOS.
51 *
52 * @return Pointer to new instance on success.\n
53 * NULL on error.
54 */
55me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base);
56
57#endif
58#endif
diff --git a/drivers/staging/meilhaus/me0600_optoi_reg.h b/drivers/staging/meilhaus/me0600_optoi_reg.h
new file mode 100644
index 000000000000..e0bc45054000
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_optoi_reg.h
@@ -0,0 +1,35 @@
1/**
2 * @file me0600_optoi_reg.h
3 *
4 * @brief ME-630 Optoisolated input subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0600_OPTOI_REG_H_
28#define _ME0600_OPTOI_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME0600_OPTO_INPUT_REG 0x0004
33
34#endif
35#endif
diff --git a/drivers/staging/meilhaus/me0600_relay.c b/drivers/staging/meilhaus/me0600_relay.c
new file mode 100644
index 000000000000..2665c69addd2
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_relay.c
@@ -0,0 +1,359 @@
1/**
2 * @file me0600_relay.c
3 *
4 * @brief ME-630 relay 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45
46#include "medebug.h"
47#include "me0600_relay_reg.h"
48#include "me0600_relay.h"
49
50/*
51 * Defines
52 */
53
54/*
55 * Functions
56 */
57
58static int me0600_relay_io_reset_subdevice(struct me_subdevice *subdevice,
59 struct file *filep, int flags)
60{
61 me0600_relay_subdevice_t *instance;
62
63 PDEBUG("executed.\n");
64
65 instance = (me0600_relay_subdevice_t *) subdevice;
66
67 if (flags) {
68 PERROR("Invalid flag specified.\n");
69 return ME_ERRNO_INVALID_FLAGS;
70 }
71
72 ME_SUBDEVICE_ENTER;
73
74 spin_lock(&instance->subdevice_lock);
75 outb(0x0, instance->port_0_reg);
76 PDEBUG_REG("port_0_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
77 instance->port_0_reg - instance->reg_base, 0);
78 outb(0x0, instance->port_1_reg);
79 PDEBUG_REG("port_1_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
80 instance->port_1_reg - instance->reg_base, 0);
81 spin_unlock(&instance->subdevice_lock);
82
83 ME_SUBDEVICE_EXIT;
84
85 return ME_ERRNO_SUCCESS;
86}
87
88static int me0600_relay_io_single_config(me_subdevice_t * subdevice,
89 struct file *filep,
90 int channel,
91 int single_config,
92 int ref,
93 int trig_chan,
94 int trig_type,
95 int trig_edge, int flags)
96{
97 me0600_relay_subdevice_t *instance;
98 int err = ME_ERRNO_SUCCESS;
99
100 PDEBUG("executed.\n");
101
102 instance = (me0600_relay_subdevice_t *) subdevice;
103
104 ME_SUBDEVICE_ENTER;
105
106 spin_lock(&instance->subdevice_lock);
107
108 switch (flags) {
109 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
110 case ME_IO_SINGLE_CONFIG_DIO_WORD:
111 if (channel == 0) {
112 if (single_config != ME_SINGLE_CONFIG_DIO_OUTPUT) {
113 PERROR("Invalid word direction specified.\n");
114 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
115 }
116 } else {
117 PERROR("Invalid channel specified.\n");
118 err = ME_ERRNO_INVALID_CHANNEL;
119 }
120
121 break;
122
123 default:
124 PERROR("Invalid flags specified.\n");
125
126 err = ME_ERRNO_INVALID_FLAGS;
127
128 break;
129 }
130
131 spin_unlock(&instance->subdevice_lock);
132
133 ME_SUBDEVICE_EXIT;
134
135 return err;
136}
137
138static int me0600_relay_io_single_read(me_subdevice_t * subdevice,
139 struct file *filep,
140 int channel,
141 int *value, int time_out, int flags)
142{
143 me0600_relay_subdevice_t *instance;
144 int err = ME_ERRNO_SUCCESS;
145
146 PDEBUG("executed.\n");
147
148 instance = (me0600_relay_subdevice_t *) subdevice;
149
150 ME_SUBDEVICE_ENTER;
151
152 spin_lock(&instance->subdevice_lock);
153
154 switch (flags) {
155
156 case ME_IO_SINGLE_TYPE_DIO_BIT:
157 if ((channel >= 0) && (channel < 8)) {
158 *value = inb(instance->port_0_reg) & (0x1 << channel);
159 } else if ((channel >= 8) && (channel < 16)) {
160 *value =
161 inb(instance->port_1_reg) & (0x1 << (channel - 8));
162 } else {
163 PERROR("Invalid bit number specified.\n");
164 err = ME_ERRNO_INVALID_CHANNEL;
165 }
166
167 break;
168
169 case ME_IO_SINGLE_TYPE_DIO_BYTE:
170 if (channel == 0) {
171 *value = inb(instance->port_0_reg);
172 } else if (channel == 1) {
173 *value = inb(instance->port_1_reg);
174 } else {
175 PERROR("Invalid byte number specified.\n");
176 err = ME_ERRNO_INVALID_CHANNEL;
177 }
178
179 break;
180
181 case ME_IO_SINGLE_NO_FLAGS:
182 case ME_IO_SINGLE_TYPE_DIO_WORD:
183 if (channel == 0) {
184 *value = (uint32_t) inb(instance->port_1_reg) << 8;
185 *value |= inb(instance->port_0_reg);
186 } else {
187 PERROR("Invalid word number specified.\n");
188 err = ME_ERRNO_INVALID_CHANNEL;
189 }
190
191 break;
192
193 default:
194 PERROR("Invalid flags specified.\n");
195
196 err = ME_ERRNO_INVALID_FLAGS;
197 }
198
199 spin_unlock(&instance->subdevice_lock);
200
201 ME_SUBDEVICE_EXIT;
202
203 return err;
204}
205
206static int me0600_relay_io_single_write(me_subdevice_t * subdevice,
207 struct file *filep,
208 int channel,
209 int value, int time_out, int flags)
210{
211 me0600_relay_subdevice_t *instance;
212 int err = ME_ERRNO_SUCCESS;
213 uint8_t state;
214
215 PDEBUG("executed.\n");
216
217 instance = (me0600_relay_subdevice_t *) subdevice;
218
219 ME_SUBDEVICE_ENTER;
220
221 spin_lock(&instance->subdevice_lock);
222
223 switch (flags) {
224 case ME_IO_SINGLE_TYPE_DIO_BIT:
225 if ((channel >= 0) && (channel < 8)) {
226 state = inb(instance->port_0_reg);
227 state =
228 value ? (state | (0x1 << channel)) : (state &
229 ~(0x1 <<
230 channel));
231 outb(state, instance->port_0_reg);
232 } else if ((channel >= 8) && (channel < 16)) {
233 state = inb(instance->port_1_reg);
234 state =
235 value ? (state | (0x1 << (channel - 8))) : (state &
236 ~(0x1 <<
237 (channel
238 -
239 8)));
240 outb(state, instance->port_1_reg);
241 } else {
242 PERROR("Invalid bit number specified.\n");
243 err = ME_ERRNO_INVALID_CHANNEL;
244 }
245 break;
246
247 case ME_IO_SINGLE_TYPE_DIO_BYTE:
248 if (channel == 0) {
249 outb(value, instance->port_0_reg);
250 } else if (channel == 1) {
251 outb(value, instance->port_1_reg);
252 } else {
253 PERROR("Invalid byte number specified.\n");
254 err = ME_ERRNO_INVALID_CHANNEL;
255 }
256 break;
257
258 case ME_IO_SINGLE_NO_FLAGS:
259 case ME_IO_SINGLE_TYPE_DIO_WORD:
260 if (channel == 0) {
261 outb(value, instance->port_0_reg);
262 outb(value >> 8, instance->port_1_reg);
263 } else {
264 PERROR("Invalid word number specified.\n");
265 err = ME_ERRNO_INVALID_CHANNEL;
266 }
267 break;
268
269 default:
270 PERROR("Invalid flags specified.\n");
271 err = ME_ERRNO_INVALID_FLAGS;
272 break;
273 }
274
275 spin_unlock(&instance->subdevice_lock);
276
277 ME_SUBDEVICE_EXIT;
278
279 return err;
280}
281
282static int me0600_relay_query_number_channels(me_subdevice_t * subdevice,
283 int *number)
284{
285 PDEBUG("executed.\n");
286 *number = 16;
287 return ME_ERRNO_SUCCESS;
288}
289
290static int me0600_relay_query_subdevice_type(me_subdevice_t * subdevice,
291 int *type, int *subtype)
292{
293 PDEBUG("executed.\n");
294 *type = ME_TYPE_DO;
295 *subtype = ME_SUBTYPE_SINGLE;
296 return ME_ERRNO_SUCCESS;
297}
298
299static int me0600_relay_query_subdevice_caps(me_subdevice_t * subdevice,
300 int *caps)
301{
302 PDEBUG("executed.\n");
303 *caps = 0;
304 return ME_ERRNO_SUCCESS;
305}
306
307me0600_relay_subdevice_t *me0600_relay_constructor(uint32_t reg_base)
308{
309 me0600_relay_subdevice_t *subdevice;
310 int err;
311
312 PDEBUG("executed.\n");
313
314 /* Allocate memory for subdevice instance */
315 subdevice = kmalloc(sizeof(me0600_relay_subdevice_t), GFP_KERNEL);
316
317 if (!subdevice) {
318 PERROR("Cannot get memory for subdevice instance.\n");
319 return NULL;
320 }
321
322 memset(subdevice, 0, sizeof(me0600_relay_subdevice_t));
323
324 /* Initialize subdevice base class */
325 err = me_subdevice_init(&subdevice->base);
326
327 if (err) {
328 PERROR("Cannot initialize subdevice base class instance.\n");
329 kfree(subdevice);
330 return NULL;
331 }
332 // Initialize spin locks.
333 spin_lock_init(&subdevice->subdevice_lock);
334
335 /* Save the subdevice index */
336 subdevice->port_0_reg = reg_base + ME0600_RELAIS_0_REG;
337 subdevice->port_1_reg = reg_base + ME0600_RELAIS_1_REG;
338#ifdef MEDEBUG_DEBUG_REG
339 subdevice->reg_base = reg_base;
340#endif
341
342 /* Overload base class methods. */
343 subdevice->base.me_subdevice_io_reset_subdevice =
344 me0600_relay_io_reset_subdevice;
345 subdevice->base.me_subdevice_io_single_config =
346 me0600_relay_io_single_config;
347 subdevice->base.me_subdevice_io_single_read =
348 me0600_relay_io_single_read;
349 subdevice->base.me_subdevice_io_single_write =
350 me0600_relay_io_single_write;
351 subdevice->base.me_subdevice_query_number_channels =
352 me0600_relay_query_number_channels;
353 subdevice->base.me_subdevice_query_subdevice_type =
354 me0600_relay_query_subdevice_type;
355 subdevice->base.me_subdevice_query_subdevice_caps =
356 me0600_relay_query_subdevice_caps;
357
358 return subdevice;
359}
diff --git a/drivers/staging/meilhaus/me0600_relay.h b/drivers/staging/meilhaus/me0600_relay.h
new file mode 100644
index 000000000000..2ce7dcab8b39
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_relay.h
@@ -0,0 +1,63 @@
1/**
2 * @file me0600_relay.h
3 *
4 * @brief ME-630 relay subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0600_RELAY_H_
28#define _ME0600_RELAY_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me0600_relay_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43
44 unsigned long port_0_reg; /**< Register holding the port status. */
45 unsigned long port_1_reg; /**< Register holding the port status. */
46#ifdef MEDEBUG_DEBUG_REG
47 unsigned long reg_base;
48#endif
49} me0600_relay_subdevice_t;
50
51/**
52 * @brief The constructor to generate a ME-630 relay subdevice instance.
53 *
54 * @param reg_base The register base address of the device as returned by the PCI BIOS.
55 * @param ctrl_reg_lock Spin lock protecting the control register.
56 *
57 * @return Pointer to new instance on success.\n
58 * NULL on error.
59 */
60me0600_relay_subdevice_t *me0600_relay_constructor(uint32_t reg_base);
61
62#endif
63#endif
diff --git a/drivers/staging/meilhaus/me0600_relay_reg.h b/drivers/staging/meilhaus/me0600_relay_reg.h
new file mode 100644
index 000000000000..ba4db2e223c5
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_relay_reg.h
@@ -0,0 +1,36 @@
1/**
2 * @file me0600_relay_reg.h
3 *
4 * @brief ME-630 relay subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0600_RELAY_REG_H_
28#define _ME0600_RELAY_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME0600_RELAIS_0_REG 0x0001
33#define ME0600_RELAIS_1_REG 0x0002
34
35#endif
36#endif
diff --git a/drivers/staging/meilhaus/me0600_ttli.c b/drivers/staging/meilhaus/me0600_ttli.c
new file mode 100644
index 000000000000..ab8e13b6f329
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_ttli.c
@@ -0,0 +1,238 @@
1/**
2 * @file me0600_ttli.c
3 *
4 * @brief ME-630 TTL 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45
46#include "medebug.h"
47#include "me0600_ttli_reg.h"
48#include "me0600_ttli.h"
49
50/*
51 * Defines
52 */
53
54/*
55 * Functions
56 */
57
58static int me0600_ttli_io_reset_subdevice(struct me_subdevice *subdevice,
59 struct file *filep, int flags)
60{
61 if (flags) {
62 PERROR("Invalid flag specified.\n");
63 return ME_ERRNO_INVALID_FLAGS;
64 }
65
66 PDEBUG("executed.\n");
67 return ME_ERRNO_SUCCESS;
68}
69
70static int me0600_ttli_io_single_config(me_subdevice_t * subdevice,
71 struct file *filep,
72 int channel,
73 int single_config,
74 int ref,
75 int trig_chan,
76 int trig_type, int trig_edge, int flags)
77{
78 me0600_ttli_subdevice_t *instance;
79 int err = ME_ERRNO_SUCCESS;
80
81 PDEBUG("executed.\n");
82
83 instance = (me0600_ttli_subdevice_t *) subdevice;
84
85 ME_SUBDEVICE_ENTER;
86
87 spin_lock(&instance->subdevice_lock);
88
89 switch (flags) {
90 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
91 case ME_IO_SINGLE_CONFIG_DIO_BYTE:
92 if (channel == 0) {
93 if (single_config != ME_SINGLE_CONFIG_DIO_INPUT) {
94 PERROR("Invalid port direction specified.\n");
95 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
96 }
97 } else {
98 PERROR("Invalid channel specified.\n");
99 err = ME_ERRNO_INVALID_CHANNEL;
100 }
101
102 break;
103
104 default:
105 PERROR("Invalid flags specified.\n");
106
107 err = ME_ERRNO_INVALID_FLAGS;
108
109 break;
110 }
111
112 spin_unlock(&instance->subdevice_lock);
113
114 ME_SUBDEVICE_EXIT;
115
116 return err;
117}
118
119static int me0600_ttli_io_single_read(me_subdevice_t * subdevice,
120 struct file *filep,
121 int channel,
122 int *value, int time_out, int flags)
123{
124 me0600_ttli_subdevice_t *instance;
125 int err = ME_ERRNO_SUCCESS;
126
127 PDEBUG("executed.\n");
128
129 instance = (me0600_ttli_subdevice_t *) subdevice;
130
131 ME_SUBDEVICE_ENTER;
132
133 spin_lock(&instance->subdevice_lock);
134
135 switch (flags) {
136 case ME_IO_SINGLE_TYPE_DIO_BIT:
137 if ((channel >= 0) && (channel < 8)) {
138 *value = inb(instance->port_reg) & (0x1 << channel);
139 } else {
140 PERROR("Invalid bit number specified.\n");
141 err = ME_ERRNO_INVALID_CHANNEL;
142 }
143 break;
144
145 case ME_IO_SINGLE_NO_FLAGS:
146 case ME_IO_SINGLE_TYPE_DIO_BYTE:
147 if (channel == 0) {
148 *value = inb(instance->port_reg);
149 } else {
150 PERROR("Invalid byte number specified.\n");
151 err = ME_ERRNO_INVALID_CHANNEL;
152 }
153 break;
154
155 default:
156 PERROR("Invalid flags specified.\n");
157 err = ME_ERRNO_INVALID_FLAGS;
158 }
159
160 spin_unlock(&instance->subdevice_lock);
161
162 ME_SUBDEVICE_EXIT;
163
164 return err;
165}
166
167static int me0600_ttli_query_number_channels(me_subdevice_t * subdevice,
168 int *number)
169{
170 PDEBUG("executed.\n");
171 *number = 8;
172 return ME_ERRNO_SUCCESS;
173}
174
175static int me0600_ttli_query_subdevice_type(me_subdevice_t * subdevice,
176 int *type, int *subtype)
177{
178 PDEBUG("executed.\n");
179 *type = ME_TYPE_DI;
180 *subtype = ME_SUBTYPE_SINGLE;
181 return ME_ERRNO_SUCCESS;
182}
183
184static int me0600_ttli_query_subdevice_caps(me_subdevice_t * subdevice,
185 int *caps)
186{
187 PDEBUG("executed.\n");
188 *caps = 0;
189 return ME_ERRNO_SUCCESS;
190}
191
192me0600_ttli_subdevice_t *me0600_ttli_constructor(uint32_t reg_base)
193{
194 me0600_ttli_subdevice_t *subdevice;
195 int err;
196
197 PDEBUG("executed.\n");
198
199 /* Allocate memory for subdevice instance */
200 subdevice = kmalloc(sizeof(me0600_ttli_subdevice_t), GFP_KERNEL);
201
202 if (!subdevice) {
203 PERROR("Cannot get memory for subdevice instance.\n");
204 return NULL;
205 }
206
207 memset(subdevice, 0, sizeof(me0600_ttli_subdevice_t));
208
209 /* Initialize subdevice base class */
210 err = me_subdevice_init(&subdevice->base);
211
212 if (err) {
213 PERROR("Cannot initialize subdevice base class instance.\n");
214 kfree(subdevice);
215 return NULL;
216 }
217 // Initialize spin locks.
218 spin_lock_init(&subdevice->subdevice_lock);
219
220 /* Save the subdevice index */
221 subdevice->port_reg = reg_base + ME0600_TTL_INPUT_REG;
222
223 /* Overload base class methods. */
224 subdevice->base.me_subdevice_io_reset_subdevice =
225 me0600_ttli_io_reset_subdevice;
226 subdevice->base.me_subdevice_io_single_config =
227 me0600_ttli_io_single_config;
228 subdevice->base.me_subdevice_io_single_read =
229 me0600_ttli_io_single_read;
230 subdevice->base.me_subdevice_query_number_channels =
231 me0600_ttli_query_number_channels;
232 subdevice->base.me_subdevice_query_subdevice_type =
233 me0600_ttli_query_subdevice_type;
234 subdevice->base.me_subdevice_query_subdevice_caps =
235 me0600_ttli_query_subdevice_caps;
236
237 return subdevice;
238}
diff --git a/drivers/staging/meilhaus/me0600_ttli.h b/drivers/staging/meilhaus/me0600_ttli.h
new file mode 100644
index 000000000000..6c9039614867
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_ttli.h
@@ -0,0 +1,58 @@
1/**
2 * @file me0600_ttli.h
3 *
4 * @brief ME-630 TTL input subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0600_TTLI_H_
28#define _ME0600_TTLI_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me0600_ttli_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43
44 uint32_t port_reg; /**< Register holding the port status. */
45} me0600_ttli_subdevice_t;
46
47/**
48 * @brief The constructor to generate a ME-630 TTL input subdevice instance.
49 *
50 * @param reg_base The register base address of the device as returned by the PCI BIOS.
51 *
52 * @return Pointer to new instance on success.\n
53 * NULL on error.
54 */
55me0600_ttli_subdevice_t *me0600_ttli_constructor(uint32_t reg_base);
56
57#endif
58#endif
diff --git a/drivers/staging/meilhaus/me0600_ttli_reg.h b/drivers/staging/meilhaus/me0600_ttli_reg.h
new file mode 100644
index 000000000000..4f986d160934
--- /dev/null
+++ b/drivers/staging/meilhaus/me0600_ttli_reg.h
@@ -0,0 +1,35 @@
1/**
2 * @file me0600_ttli_reg.h
3 *
4 * @brief ME-630 TTL input subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0600_TTLI_REG_H_
28#define _ME0600_TTLI_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME0600_TTL_INPUT_REG 0x0003
33
34#endif
35#endif
diff --git a/drivers/staging/meilhaus/me0900_device.c b/drivers/staging/meilhaus/me0900_device.c
new file mode 100644
index 000000000000..764d5d307c44
--- /dev/null
+++ b/drivers/staging/meilhaus/me0900_device.c
@@ -0,0 +1,180 @@
1/**
2 * @file me0900_device.c
3 *
4 * @brief ME-9x device class implementation.
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#ifndef MODULE
33# define MODULE
34#endif
35
36#include <linux/module.h>
37
38#include <linux/pci.h>
39#include <linux/slab.h>
40
41#include "meids.h"
42#include "meerror.h"
43#include "mecommon.h"
44#include "meinternal.h"
45
46#include "medebug.h"
47#include "medevice.h"
48#include "me0900_device.h"
49#include "me0900_reg.h"
50#include "mesubdevice.h"
51#include "me0900_do.h"
52#include "me0900_di.h"
53
54me_device_t *me0900_pci_constructor(struct pci_dev *pci_device)
55{
56 me0900_device_t *me0900_device;
57 me_subdevice_t *subdevice;
58 unsigned int version_idx;
59 int err;
60 int i;
61 int port_shift;
62
63 PDEBUG("executed.\n");
64
65 // Allocate structure for device instance.
66 me0900_device = kmalloc(sizeof(me0900_device_t), GFP_KERNEL);
67
68 if (!me0900_device) {
69 PERROR("Cannot get memory for device instance.\n");
70 return NULL;
71 }
72
73 memset(me0900_device, 0, sizeof(me0900_device_t));
74
75 // Initialize base class structure.
76 err = me_device_pci_init((me_device_t *) me0900_device, pci_device);
77
78 if (err) {
79 kfree(me0900_device);
80 PERROR("Cannot initialize device base class.\n");
81 return NULL;
82 }
83
84 /* Get the index in the device version information table. */
85 version_idx =
86 me0900_versions_get_device_index(me0900_device->base.info.pci.
87 device_id);
88
89 /* Initialize 8255 chip to desired mode */
90 if (me0900_device->base.info.pci.device_id ==
91 PCI_DEVICE_ID_MEILHAUS_ME0940) {
92 outb(0x9B,
93 me0900_device->base.info.pci.reg_bases[2] +
94 ME0900_CTRL_REG);
95 } else if (me0900_device->base.info.pci.device_id ==
96 PCI_DEVICE_ID_MEILHAUS_ME0950) {
97 outb(0x89,
98 me0900_device->base.info.pci.reg_bases[2] +
99 ME0900_CTRL_REG);
100 outb(0x00,
101 me0900_device->base.info.pci.reg_bases[2] +
102 ME0900_WRITE_ENABLE_REG);
103 } else if (me0900_device->base.info.pci.device_id ==
104 PCI_DEVICE_ID_MEILHAUS_ME0960) {
105 outb(0x8B,
106 me0900_device->base.info.pci.reg_bases[2] +
107 ME0900_CTRL_REG);
108 outb(0x00,
109 me0900_device->base.info.pci.reg_bases[2] +
110 ME0900_WRITE_ENABLE_REG);
111 }
112
113 port_shift =
114 (me0900_device->base.info.pci.device_id ==
115 PCI_DEVICE_ID_MEILHAUS_ME0960) ? 1 : 0;
116 // Create subdevice instances.
117
118 for (i = 0; i < me0900_versions[version_idx].di_subdevices; i++) {
119 subdevice =
120 (me_subdevice_t *) me0900_di_constructor(me0900_device->
121 base.info.pci.
122 reg_bases[2],
123 i + port_shift);
124
125 if (!subdevice) {
126 me_device_deinit((me_device_t *) me0900_device);
127 kfree(me0900_device);
128 PERROR("Cannot get memory for subdevice.\n");
129 return NULL;
130 }
131
132 me_slist_add_subdevice_tail(&me0900_device->base.slist,
133 subdevice);
134 }
135
136 for (i = 0; i < me0900_versions[version_idx].do_subdevices; i++) {
137 subdevice =
138 (me_subdevice_t *) me0900_do_constructor(me0900_device->
139 base.info.pci.
140 reg_bases[2], i);
141
142 if (!subdevice) {
143 me_device_deinit((me_device_t *) me0900_device);
144 kfree(me0900_device);
145 PERROR("Cannot get memory for subdevice.\n");
146 return NULL;
147 }
148
149 me_slist_add_subdevice_tail(&me0900_device->base.slist,
150 subdevice);
151 }
152
153 return (me_device_t *) me0900_device;
154}
155
156// Init and exit of module.
157
158static int __init me0900_init(void)
159{
160 PDEBUG("executed.\n.");
161 return 0;
162}
163
164static void __exit me0900_exit(void)
165{
166 PDEBUG("executed.\n.");
167}
168
169module_init(me0900_init);
170module_exit(me0900_exit);
171
172// Administrative stuff for modinfo.
173MODULE_AUTHOR
174 ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
175MODULE_DESCRIPTION("Device Driver Module for ME-9x Device");
176MODULE_SUPPORTED_DEVICE("Meilhaus ME-9x Devices");
177MODULE_LICENSE("GPL");
178
179// Export the constructor.
180EXPORT_SYMBOL(me0900_pci_constructor);
diff --git a/drivers/staging/meilhaus/me0900_device.h b/drivers/staging/meilhaus/me0900_device.h
new file mode 100644
index 000000000000..bd17f2521511
--- /dev/null
+++ b/drivers/staging/meilhaus/me0900_device.h
@@ -0,0 +1,92 @@
1/**
2 * @file me0900_device.h
3 *
4 * @brief ME-0900 (ME-9x) device class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0900_DEVICE_H
28#define _ME0900_DEVICE_H
29
30#include <linux/pci.h>
31#include <linux/spinlock.h>
32
33#include "medevice.h"
34
35#ifdef __KERNEL__
36
37/**
38 * @brief Structure holding ME-0900 (ME-9x) device capabilities.
39 */
40typedef struct me0900_version {
41 uint16_t device_id;
42 unsigned int di_subdevices;
43 unsigned int do_subdevices;
44} me0900_version_t;
45
46/**
47 * @brief Device capabilities.
48 */
49static me0900_version_t me0900_versions[] = {
50 {PCI_DEVICE_ID_MEILHAUS_ME0940, 2, 0},
51 {PCI_DEVICE_ID_MEILHAUS_ME0950, 0, 2},
52 {PCI_DEVICE_ID_MEILHAUS_ME0960, 1, 1},
53 {0},
54};
55
56#define ME0900_DEVICE_VERSIONS (sizeof(me0900_versions) / sizeof(me0900_version_t) - 1) /**< Returns the number of entries in #me0900_versions. */
57
58/**
59 * @brief Returns the index of the device entry in #me0900_versions.
60 *
61 * @param device_id The PCI device id of the device to query.
62 * @return The index of the device in #me0900_versions.
63 */
64static inline unsigned int me0900_versions_get_device_index(uint16_t device_id)
65{
66 unsigned int i;
67 for (i = 0; i < ME0900_DEVICE_VERSIONS; i++)
68 if (me0900_versions[i].device_id == device_id)
69 break;
70 return i;
71}
72
73/**
74 * @brief The ME-0900 (ME-9x) device class structure.
75 */
76typedef struct me0900_device {
77 me_device_t base; /**< The Meilhaus device base class. */
78} me0900_device_t;
79
80/**
81 * @brief The ME-9x device class constructor.
82 *
83 * @param pci_device The pci device structure given by the PCI subsystem.
84 *
85 * @return On succes a new ME-0900 (ME-9x) device instance. \n
86 * NULL on error.
87 */
88me_device_t *me0900_pci_constructor(struct pci_dev *pci_device)
89 __attribute__ ((weak));
90
91#endif
92#endif
diff --git a/drivers/staging/meilhaus/me0900_di.c b/drivers/staging/meilhaus/me0900_di.c
new file mode 100644
index 000000000000..d7d7394f800a
--- /dev/null
+++ b/drivers/staging/meilhaus/me0900_di.c
@@ -0,0 +1,246 @@
1/**
2 * @file me0900_di.c
3 *
4 * @brief ME-9x digital input subdevice instance.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef __KERNEL__
28# define __KERNEL__
29#endif
30
31/*
32 * Includes
33 */
34#include <linux/module.h>
35
36#include <linux/slab.h>
37#include <linux/spinlock.h>
38#include <asm/io.h>
39#include <linux/types.h>
40#include <linux/interrupt.h>
41#include <linux/version.h>
42
43#include "medefines.h"
44#include "meinternal.h"
45#include "meerror.h"
46
47#include "meids.h"
48#include "medebug.h"
49#include "meplx_reg.h"
50#include "me0900_reg.h"
51#include "me0900_di.h"
52
53/*
54 * Defines
55 */
56
57/*
58 * Functions
59 */
60
61static int me0900_di_io_reset_subdevice(struct me_subdevice *subdevice,
62 struct file *filep, int flags)
63{
64 PDEBUG("executed.\n");
65
66 if (flags) {
67 PERROR("Invalid flag specified.\n");
68 return ME_ERRNO_INVALID_FLAGS;
69 }
70
71 return ME_ERRNO_SUCCESS;
72}
73
74static int me0900_di_io_single_config(me_subdevice_t * subdevice,
75 struct file *filep,
76 int channel,
77 int single_config,
78 int ref,
79 int trig_chan,
80 int trig_type, int trig_edge, int flags)
81{
82 me0900_di_subdevice_t *instance;
83 int err = ME_ERRNO_SUCCESS;
84
85 PDEBUG("executed.\n");
86
87 instance = (me0900_di_subdevice_t *) subdevice;
88
89 ME_SUBDEVICE_ENTER;
90
91 spin_lock(&instance->subdevice_lock);
92 switch (flags) {
93 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
94 case ME_IO_SINGLE_TYPE_DIO_BYTE:
95 if (channel == 0) {
96 if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
97 } else {
98 PERROR("Invalid byte direction specified.\n");
99 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
100 }
101 } else {
102 PERROR("Invalid byte number specified.\n");
103 err = ME_ERRNO_INVALID_CHANNEL;
104 }
105 break;
106
107 default:
108 PERROR("Invalid flags specified.\n");
109 err = ME_ERRNO_INVALID_FLAGS;
110 }
111 spin_unlock(&instance->subdevice_lock);
112
113 ME_SUBDEVICE_EXIT;
114
115 return err;
116}
117
118static int me0900_di_io_single_read(me_subdevice_t * subdevice,
119 struct file *filep,
120 int channel,
121 int *value, int time_out, int flags)
122{
123 me0900_di_subdevice_t *instance;
124 int err = ME_ERRNO_SUCCESS;
125
126 PDEBUG("executed.\n");
127
128 instance = (me0900_di_subdevice_t *) subdevice;
129
130 ME_SUBDEVICE_ENTER;
131
132 spin_lock(&instance->subdevice_lock);
133 switch (flags) {
134 case ME_IO_SINGLE_TYPE_DIO_BIT:
135 if ((channel >= 0) && (channel < 8)) {
136 *value = (~inb(instance->port_reg)) & (0x1 << channel);
137 } else {
138 PERROR("Invalid bit number specified.\n");
139 err = ME_ERRNO_INVALID_CHANNEL;
140 }
141 break;
142
143 case ME_IO_SINGLE_NO_FLAGS:
144 case ME_IO_SINGLE_TYPE_DIO_BYTE:
145 if (channel == 0) {
146 *value = ~inb(instance->port_reg);
147 } else {
148 PERROR("Invalid byte number specified.\n");
149 err = ME_ERRNO_INVALID_CHANNEL;
150 }
151 break;
152
153 default:
154 PERROR("Invalid flags specified.\n");
155 err = ME_ERRNO_INVALID_FLAGS;
156 }
157 spin_unlock(&instance->subdevice_lock);
158
159 ME_SUBDEVICE_EXIT;
160
161 return err;
162}
163
164static int me0900_di_query_number_channels(me_subdevice_t * subdevice,
165 int *number)
166{
167 PDEBUG("executed.\n");
168 *number = 8;
169 return ME_ERRNO_SUCCESS;
170}
171
172static int me0900_di_query_subdevice_type(me_subdevice_t * subdevice,
173 int *type, int *subtype)
174{
175 PDEBUG("executed.\n");
176 *type = ME_TYPE_DI;
177 *subtype = ME_SUBTYPE_SINGLE;
178 return ME_ERRNO_SUCCESS;
179}
180
181static int me0900_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
182{
183 PDEBUG("executed.\n");
184 *caps = 0;
185 return ME_ERRNO_SUCCESS;
186}
187
188me0900_di_subdevice_t *me0900_di_constructor(uint32_t reg_base,
189 unsigned int di_idx)
190{
191 me0900_di_subdevice_t *subdevice;
192 int err;
193
194 PDEBUG("executed.\n");
195
196 /* Allocate memory for subdevice instance */
197 subdevice = kmalloc(sizeof(me0900_di_subdevice_t), GFP_KERNEL);
198
199 if (!subdevice) {
200 PERROR("Cannot get memory for subdevice instance.\n");
201 return NULL;
202 }
203
204 memset(subdevice, 0, sizeof(me0900_di_subdevice_t));
205
206 /* Initialize subdevice base class */
207 err = me_subdevice_init(&subdevice->base);
208
209 if (err) {
210 PERROR("Cannot initialize subdevice base class instance.\n");
211 kfree(subdevice);
212 return NULL;
213 }
214 // Initialize spin locks.
215 spin_lock_init(&subdevice->subdevice_lock);
216
217 /* Save the subdevice index. */
218 subdevice->di_idx = di_idx;
219
220 /* Initialize registers */
221 if (di_idx == 0) {
222 subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
223 subdevice->port_reg = reg_base + ME0900_PORT_A_REG;
224 } else {
225 subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
226 subdevice->port_reg = reg_base + ME0900_PORT_B_REG;
227 }
228#ifdef MEDEBUG_DEBUG_REG
229 subdevice->reg_base = reg_base;
230#endif
231
232 /* Overload base class methods. */
233 subdevice->base.me_subdevice_io_reset_subdevice =
234 me0900_di_io_reset_subdevice;
235 subdevice->base.me_subdevice_io_single_config =
236 me0900_di_io_single_config;
237 subdevice->base.me_subdevice_io_single_read = me0900_di_io_single_read;
238 subdevice->base.me_subdevice_query_number_channels =
239 me0900_di_query_number_channels;
240 subdevice->base.me_subdevice_query_subdevice_type =
241 me0900_di_query_subdevice_type;
242 subdevice->base.me_subdevice_query_subdevice_caps =
243 me0900_di_query_subdevice_caps;
244
245 return subdevice;
246}
diff --git a/drivers/staging/meilhaus/me0900_di.h b/drivers/staging/meilhaus/me0900_di.h
new file mode 100644
index 000000000000..014f1348fc9f
--- /dev/null
+++ b/drivers/staging/meilhaus/me0900_di.h
@@ -0,0 +1,65 @@
1/**
2 * @file me0900_di.h
3 *
4 * @brief ME-9x digital input subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0900_DI_H_
28#define _ME0900_DI_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me0900_di_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43
44 unsigned int di_idx;
45
46 unsigned long ctrl_reg;
47 unsigned long port_reg;
48#ifdef MEDEBUG_DEBUG_REG
49 unsigned long reg_base;
50#endif
51} me0900_di_subdevice_t;
52
53/**
54 * @brief The constructor to generate a ME-9x digital input subdevice instance.
55 *
56 * @param reg_base The register base address of the device as returned by the PCI BIOS.
57 *
58 * @return Pointer to new instance on success.\n
59 * NULL on error.
60 */
61me0900_di_subdevice_t *me0900_di_constructor(uint32_t me0900_reg_base,
62 unsigned int di_idx);
63
64#endif
65#endif
diff --git a/drivers/staging/meilhaus/me0900_do.c b/drivers/staging/meilhaus/me0900_do.c
new file mode 100644
index 000000000000..b5b9c3a98c94
--- /dev/null
+++ b/drivers/staging/meilhaus/me0900_do.c
@@ -0,0 +1,314 @@
1/**
2 * @file me0900_do.c
3 *
4 * @brief ME-9x digital output subdevice instance.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef __KERNEL__
28# define __KERNEL__
29#endif
30
31/*
32 * Includes
33 */
34#include <linux/module.h>
35
36#include <linux/slab.h>
37#include <linux/spinlock.h>
38#include <asm/io.h>
39#include <linux/types.h>
40
41#include "medefines.h"
42#include "meinternal.h"
43#include "meerror.h"
44
45#include "medebug.h"
46#include "me0900_reg.h"
47#include "me0900_do.h"
48
49/*
50 * Defines
51 */
52
53/*
54 * Functions
55 */
56
57static int me0900_do_io_reset_subdevice(struct me_subdevice *subdevice,
58 struct file *filep, int flags)
59{
60 me0900_do_subdevice_t *instance;
61
62 PDEBUG("executed.\n");
63
64 instance = (me0900_do_subdevice_t *) subdevice;
65
66 if (flags) {
67 PERROR("Invalid flag specified.\n");
68 return ME_ERRNO_INVALID_FLAGS;
69 }
70
71 ME_SUBDEVICE_ENTER;
72
73 spin_lock(&instance->subdevice_lock);
74 outb(0xFF, instance->port_reg);
75 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
76 instance->port_reg - instance->reg_base, 0xff);
77 spin_unlock(&instance->subdevice_lock);
78
79 ME_SUBDEVICE_EXIT;
80
81 return ME_ERRNO_SUCCESS;
82}
83
84static int me0900_do_io_single_config(me_subdevice_t * subdevice,
85 struct file *filep,
86 int channel,
87 int single_config,
88 int ref,
89 int trig_chan,
90 int trig_type, int trig_edge, int flags)
91{
92 me0900_do_subdevice_t *instance;
93 int err = ME_ERRNO_SUCCESS;
94
95 PDEBUG("executed.\n");
96
97 instance = (me0900_do_subdevice_t *) subdevice;
98
99 ME_SUBDEVICE_ENTER;
100
101 spin_lock(&instance->subdevice_lock);
102 switch (flags) {
103 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
104 case ME_IO_SINGLE_TYPE_DIO_BYTE:
105 if (channel == 0) {
106 if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
107 } else {
108 PERROR("Invalid byte direction specified.\n");
109 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
110 }
111 } else {
112 PERROR("Invalid byte number specified.\n");
113 err = ME_ERRNO_INVALID_CHANNEL;
114 }
115 break;
116
117 default:
118 PERROR("Invalid flags specified.\n");
119 err = ME_ERRNO_INVALID_FLAGS;
120 }
121 spin_unlock(&instance->subdevice_lock);
122
123 ME_SUBDEVICE_EXIT;
124
125 return err;
126}
127
128static int me0900_do_io_single_read(me_subdevice_t * subdevice,
129 struct file *filep,
130 int channel,
131 int *value, int time_out, int flags)
132{
133 me0900_do_subdevice_t *instance;
134 int err = ME_ERRNO_SUCCESS;
135
136 PDEBUG("executed.\n");
137
138 instance = (me0900_do_subdevice_t *) subdevice;
139
140 ME_SUBDEVICE_ENTER;
141
142 spin_lock(&instance->subdevice_lock);
143 switch (flags) {
144 case ME_IO_SINGLE_TYPE_DIO_BIT:
145 if ((channel >= 0) && (channel < 8)) {
146 *value = (~inb(instance->port_reg)) & (0x1 << channel);
147 } else {
148 PERROR("Invalid bit number specified.\n");
149 err = ME_ERRNO_INVALID_CHANNEL;
150 }
151 break;
152
153 case ME_IO_SINGLE_NO_FLAGS:
154 case ME_IO_SINGLE_TYPE_DIO_BYTE:
155 if (channel == 0) {
156 *value = ~inb(instance->port_reg);
157 } else {
158 PERROR("Invalid byte number specified.\n");
159 err = ME_ERRNO_INVALID_CHANNEL;
160 }
161 break;
162
163 default:
164 PERROR("Invalid flags specified.\n");
165 err = ME_ERRNO_INVALID_FLAGS;
166 }
167 spin_unlock(&instance->subdevice_lock);
168
169 ME_SUBDEVICE_EXIT;
170
171 return err;
172}
173
174static int me0900_do_io_single_write(me_subdevice_t * subdevice,
175 struct file *filep,
176 int channel,
177 int value, int time_out, int flags)
178{
179 me0900_do_subdevice_t *instance;
180 int err = ME_ERRNO_SUCCESS;
181 unsigned long state;
182
183 PDEBUG("executed.\n");
184
185 instance = (me0900_do_subdevice_t *) subdevice;
186
187 ME_SUBDEVICE_ENTER;
188
189 spin_lock(&instance->subdevice_lock);
190 switch (flags) {
191 case ME_IO_SINGLE_TYPE_DIO_BIT:
192 if ((channel >= 0) && (channel < 8)) {
193 state = inb(instance->port_reg);
194 state =
195 (!value) ? (state | (0x1 << channel)) : (state &
196 ~(0x1 <<
197 channel));
198 outb(state, instance->port_reg);
199 } else {
200 PERROR("Invalid bit number specified.\n");
201 err = ME_ERRNO_INVALID_CHANNEL;
202 }
203 break;
204
205 case ME_IO_SINGLE_NO_FLAGS:
206 case ME_IO_SINGLE_TYPE_DIO_BYTE:
207 if (channel == 0) {
208 outb(~(value), instance->port_reg);
209 } else {
210 PERROR("Invalid byte number specified.\n");
211 err = ME_ERRNO_INVALID_CHANNEL;
212 }
213 break;
214
215 default:
216 PERROR("Invalid flags specified.\n");
217 err = ME_ERRNO_INVALID_FLAGS;
218 }
219 spin_unlock(&instance->subdevice_lock);
220
221 ME_SUBDEVICE_EXIT;
222
223 return err;
224}
225
226static int me0900_do_query_number_channels(me_subdevice_t * subdevice,
227 int *number)
228{
229 PDEBUG("executed.\n");
230 *number = 8;
231 return ME_ERRNO_SUCCESS;
232}
233
234static int me0900_do_query_subdevice_type(me_subdevice_t * subdevice,
235 int *type, int *subtype)
236{
237 PDEBUG("executed.\n");
238 *type = ME_TYPE_DO;
239 *subtype = ME_SUBTYPE_SINGLE;
240 return ME_ERRNO_SUCCESS;
241}
242
243static int me0900_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
244{
245 PDEBUG("executed.\n");
246 *caps = 0;
247 return ME_ERRNO_SUCCESS;
248}
249
250me0900_do_subdevice_t *me0900_do_constructor(uint32_t reg_base,
251 unsigned int do_idx)
252{
253 me0900_do_subdevice_t *subdevice;
254 int err;
255
256 PDEBUG("executed.\n");
257
258 /* Allocate memory for subdevice instance */
259 subdevice = kmalloc(sizeof(me0900_do_subdevice_t), GFP_KERNEL);
260
261 if (!subdevice) {
262 PERROR("Cannot get memory for subdevice instance.\n");
263 return NULL;
264 }
265
266 memset(subdevice, 0, sizeof(me0900_do_subdevice_t));
267
268 /* Initialize subdevice base class */
269 err = me_subdevice_init(&subdevice->base);
270
271 if (err) {
272 PERROR("Cannot initialize subdevice base class instance.\n");
273 kfree(subdevice);
274 return NULL;
275 }
276 // Initialize spin locks.
277 spin_lock_init(&subdevice->subdevice_lock);
278
279 /* Save the subdevice index */
280 subdevice->do_idx = do_idx;
281
282 /* Initialize registers */
283 if (do_idx == 0) {
284 subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
285 subdevice->port_reg = reg_base + ME0900_PORT_A_REG;
286 subdevice->enable_reg = reg_base + ME0900_WRITE_ENABLE_REG;
287 subdevice->disable_reg = reg_base + ME0900_WRITE_DISABLE_REG;
288 } else {
289 subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
290 subdevice->port_reg = reg_base + ME0900_PORT_B_REG;
291 subdevice->enable_reg = reg_base + ME0900_WRITE_ENABLE_REG;
292 subdevice->disable_reg = reg_base + ME0900_WRITE_DISABLE_REG;
293 }
294#ifdef MEDEBUG_DEBUG_REG
295 subdevice->reg_base = reg_base;
296#endif
297
298 /* Overload base class methods. */
299 subdevice->base.me_subdevice_io_reset_subdevice =
300 me0900_do_io_reset_subdevice;
301 subdevice->base.me_subdevice_io_single_config =
302 me0900_do_io_single_config;
303 subdevice->base.me_subdevice_io_single_read = me0900_do_io_single_read;
304 subdevice->base.me_subdevice_io_single_write =
305 me0900_do_io_single_write;
306 subdevice->base.me_subdevice_query_number_channels =
307 me0900_do_query_number_channels;
308 subdevice->base.me_subdevice_query_subdevice_type =
309 me0900_do_query_subdevice_type;
310 subdevice->base.me_subdevice_query_subdevice_caps =
311 me0900_do_query_subdevice_caps;
312
313 return subdevice;
314}
diff --git a/drivers/staging/meilhaus/me0900_do.h b/drivers/staging/meilhaus/me0900_do.h
new file mode 100644
index 000000000000..13e8a8b94cfa
--- /dev/null
+++ b/drivers/staging/meilhaus/me0900_do.h
@@ -0,0 +1,68 @@
1/**
2 * @file me0900_do.h
3 *
4 * @brief ME-9x digital output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0900_DO_H_
28#define _ME0900_DO_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me0900_do_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43
44 unsigned int do_idx;
45
46 unsigned long ctrl_reg;
47 unsigned long port_reg;
48 unsigned long enable_reg;
49 unsigned long disable_reg;
50#ifdef MEDEBUG_DEBUG_REG
51 unsigned long reg_base;
52#endif
53} me0900_do_subdevice_t;
54
55/**
56 * @brief The constructor to generate a ME-9x digital output subdevice instance.
57 *
58 * @param reg_base The register base address of the device as returned by the PCI BIOS.
59 * @param do_idx The index of the digital output subdevice on this device.
60 *
61 * @return Pointer to new instance on success.\n
62 * NULL on error.
63 */
64me0900_do_subdevice_t *me0900_do_constructor(uint32_t reg_base,
65 unsigned int do_idx);
66
67#endif
68#endif
diff --git a/drivers/staging/meilhaus/me0900_reg.h b/drivers/staging/meilhaus/me0900_reg.h
new file mode 100644
index 000000000000..3bf163b6ac49
--- /dev/null
+++ b/drivers/staging/meilhaus/me0900_reg.h
@@ -0,0 +1,40 @@
1/**
2 * @file me0900_reg.h
3 *
4 * @brief ME-9x register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME0900_REG_H_
28#define _ME0900_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME0900_PORT_A_REG 0x00
33#define ME0900_PORT_B_REG 0x01
34#define ME0900_PORT_C_REG 0x02
35#define ME0900_CTRL_REG 0x03 // ( ,w)
36#define ME0900_WRITE_ENABLE_REG 0x04 // (r,w)
37#define ME0900_WRITE_DISABLE_REG 0x08 // (r,w)
38
39#endif
40#endif
diff --git a/drivers/staging/meilhaus/me1000_device.c b/drivers/staging/meilhaus/me1000_device.c
new file mode 100644
index 000000000000..c44e214af26c
--- /dev/null
+++ b/drivers/staging/meilhaus/me1000_device.c
@@ -0,0 +1,208 @@
1/**
2 * @file me1000_device.c
3 *
4 * @brief ME-1000 device class implementation.
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#ifndef MODULE
33# define MODULE
34#endif
35
36#include <linux/module.h>
37
38#include <linux/pci.h>
39#include <linux/slab.h>
40
41#include "meids.h"
42#include "meerror.h"
43#include "mecommon.h"
44#include "meinternal.h"
45
46#include "medebug.h"
47#include "medevice.h"
48#include "me1000_device.h"
49#include "mesubdevice.h"
50#include "me1000_dio.h"
51
52static int me1000_config_load(me_device_t * me_device, struct file *filep,
53 me_cfg_device_entry_t * config)
54{
55 me1000_device_t *me1000_device;
56 me1000_dio_subdevice_t *dio;
57
58 PDEBUG("executed.\n");
59
60 me1000_device = (me1000_device_t *) me_device;
61
62 if (config->count == 2) {
63 if (me_slist_get_number_subdevices(&me1000_device->base.slist)
64 == 2) {
65 // Nothing to do.
66 } else {
67 // Remove 2 extra subdevices
68 dio =
69 (me1000_dio_subdevice_t *)
70 me_slist_del_subdevice_tail(&me1000_device->base.
71 slist);
72 if (dio)
73 dio->base.
74 me_subdevice_destructor((me_subdevice_t *)
75 dio);
76
77 dio =
78 (me1000_dio_subdevice_t *)
79 me_slist_del_subdevice_tail(&me1000_device->base.
80 slist);
81 if (dio)
82 dio->base.
83 me_subdevice_destructor((me_subdevice_t *)
84 dio);
85 }
86 } else if (config->count == 4) {
87 //Add 2 subdevices
88 if (me_slist_get_number_subdevices(&me1000_device->base.slist)
89 == 2) {
90 dio =
91 me1000_dio_constructor(me1000_device->base.info.pci.
92 reg_bases[2], 2,
93 &me1000_device->ctrl_lock);
94 if (!dio) {
95 PERROR("Cannot create dio subdevice.\n");
96 return ME_ERRNO_INTERNAL;
97 }
98 me_slist_add_subdevice_tail(&me1000_device->base.slist,
99 (me_subdevice_t *) dio);
100
101 dio =
102 me1000_dio_constructor(me1000_device->base.info.pci.
103 reg_bases[2], 3,
104 &me1000_device->ctrl_lock);
105 if (!dio) {
106 dio =
107 (me1000_dio_subdevice_t *)
108 me_slist_del_subdevice_tail(&me1000_device->
109 base.slist);
110 if (dio)
111 dio->base.
112 me_subdevice_destructor((me_subdevice_t *) dio);
113
114 PERROR("Cannot create dio subdevice.\n");
115 return ME_ERRNO_INTERNAL;
116 }
117 me_slist_add_subdevice_tail(&me1000_device->base.slist,
118 (me_subdevice_t *) dio);
119 } else {
120 // Nothing to do.
121 }
122 } else {
123 PERROR("Invalid configuration.\n");
124 return ME_ERRNO_INTERNAL;
125 }
126
127 return ME_ERRNO_SUCCESS;
128}
129
130me_device_t *me1000_pci_constructor(struct pci_dev * pci_device)
131{
132 me1000_device_t *me1000_device;
133 me_subdevice_t *subdevice;
134 int err;
135 int i;
136
137 PDEBUG("executed.\n");
138
139 // Allocate structure for device instance.
140 me1000_device = kmalloc(sizeof(me1000_device_t), GFP_KERNEL);
141
142 if (!me1000_device) {
143 PERROR("Cannot get memory for ME-1000 device instance.\n");
144 return NULL;
145 }
146
147 memset(me1000_device, 0, sizeof(me1000_device_t));
148
149 // Initialize base class structure.
150 err = me_device_pci_init((me_device_t *) me1000_device, pci_device);
151
152 if (err) {
153 kfree(me1000_device);
154 PERROR("Cannot initialize device base class.\n");
155 return NULL;
156 }
157 // Initialize spin lock .
158 spin_lock_init(&me1000_device->ctrl_lock);
159
160 for (i = 0; i < 4; i++) {
161 subdevice =
162 (me_subdevice_t *) me1000_dio_constructor(me1000_device->
163 base.info.pci.
164 reg_bases[2], i,
165 &me1000_device->
166 ctrl_lock);
167
168 if (!subdevice) {
169 me_device_deinit((me_device_t *) me1000_device);
170 kfree(me1000_device);
171 PERROR("Cannot get memory for subdevice.\n");
172 return NULL;
173 }
174
175 me_slist_add_subdevice_tail(&me1000_device->base.slist,
176 subdevice);
177 }
178
179 // Overwrite base class methods.
180 me1000_device->base.me_device_config_load = me1000_config_load;
181
182 return (me_device_t *) me1000_device;
183}
184
185// Init and exit of module.
186static int __init me1000_init(void)
187{
188 PDEBUG("executed.\n");
189 return 0;
190}
191
192static void __exit me1000_exit(void)
193{
194 PDEBUG("executed.\n");
195}
196
197module_init(me1000_init);
198module_exit(me1000_exit);
199
200// Administrative stuff for modinfo.
201MODULE_AUTHOR
202 ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
203MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-1000 Devices");
204MODULE_SUPPORTED_DEVICE("Meilhaus ME-1000 Digital I/O Devices");
205MODULE_LICENSE("GPL");
206
207// Export the constructor.
208EXPORT_SYMBOL(me1000_pci_constructor);
diff --git a/drivers/staging/meilhaus/me1000_device.h b/drivers/staging/meilhaus/me1000_device.h
new file mode 100644
index 000000000000..cbbe1263017d
--- /dev/null
+++ b/drivers/staging/meilhaus/me1000_device.h
@@ -0,0 +1,59 @@
1/**
2 * @file me1000_device.h
3 *
4 * @brief ME-1000 device class instance.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME1000_H_
28#define _ME1000_H_
29
30#include <linux/pci.h>
31#include <linux/spinlock.h>
32
33#include "medevice.h"
34
35#ifdef __KERNEL__
36
37#define ME1000_MAGIC_NUMBER 1000
38
39/**
40 * @brief The ME-1000 device class structure.
41 */
42typedef struct me1000_device {
43 me_device_t base; /**< The Meilhaus device base class. */
44 spinlock_t ctrl_lock; /**< Guards the DIO mode register. */
45} me1000_device_t;
46
47/**
48 * @brief The ME-1000 device class constructor.
49 *
50 * @param pci_device The pci device structure given by the PCI subsystem.
51 *
52 * @return On succes a new ME-1000 device instance. \n
53 * NULL on error.
54 */
55me_device_t *me1000_pci_constructor(struct pci_dev *pci_device)
56 __attribute__ ((weak));
57
58#endif
59#endif
diff --git a/drivers/staging/meilhaus/me1000_dio.c b/drivers/staging/meilhaus/me1000_dio.c
new file mode 100644
index 000000000000..87605a9108ae
--- /dev/null
+++ b/drivers/staging/meilhaus/me1000_dio.c
@@ -0,0 +1,438 @@
1/**
2 * @file me1000_dio.c
3 *
4 * @brief ME-1000 DIO subdevice instance.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 * @author Krzysztof Gantzke (k.gantzke@meilhaus.de)
8 */
9
10/*
11 * Copyright (C) 2006 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45#include "medebug.h"
46
47#include "me1000_dio_reg.h"
48#include "me1000_dio.h"
49
50/*
51 * Defines
52 */
53#define ME1000_DIO_MAGIC_NUMBER 0x1000 /**< The magic number of the class structure. */
54
55/*
56 * Functions
57 */
58
59static int me1000_dio_io_reset_subdevice(struct me_subdevice *subdevice,
60 struct file *filep, int flags)
61{
62 me1000_dio_subdevice_t *instance;
63 uint32_t tmp;
64
65 PDEBUG("executed.\n");
66
67 instance = (me1000_dio_subdevice_t *) subdevice;
68
69 if (flags) {
70 PERROR("Invalid flag specified.\n");
71 return ME_ERRNO_INVALID_FLAGS;
72 }
73
74 ME_SUBDEVICE_ENTER;
75
76 spin_lock(&instance->subdevice_lock);
77 spin_lock(instance->ctrl_reg_lock);
78 tmp = inl(instance->ctrl_reg);
79 tmp &= ~(0x1 << instance->dio_idx);
80 outl(tmp, instance->ctrl_reg);
81 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
82 instance->ctrl_reg - instance->reg_base, tmp);
83 spin_unlock(instance->ctrl_reg_lock);
84
85 outl(0x00000000, instance->port_reg);
86 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
87 instance->ctrl_reg - instance->reg_base, 0);
88 spin_unlock(&instance->subdevice_lock);
89
90 ME_SUBDEVICE_EXIT;
91
92 return ME_ERRNO_SUCCESS;
93}
94
95static int me1000_dio_io_single_config(struct me_subdevice *subdevice,
96 struct file *filep,
97 int channel,
98 int single_config,
99 int ref,
100 int trig_chan,
101 int trig_type, int trig_edge, int flags)
102{
103 me1000_dio_subdevice_t *instance;
104 int err = ME_ERRNO_SUCCESS;
105 int ctrl;
106 int size =
107 flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
108 | ME_IO_SINGLE_CONFIG_DIO_WORD |
109 ME_IO_SINGLE_CONFIG_DIO_DWORD);
110
111 PDEBUG("executed.\n");
112
113 instance = (me1000_dio_subdevice_t *) subdevice;
114
115 ME_SUBDEVICE_ENTER;
116
117 spin_lock(&instance->subdevice_lock);
118 spin_lock(instance->ctrl_reg_lock);
119 ctrl = inl(instance->ctrl_reg);
120
121 switch (size) {
122 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
123 case ME_IO_SINGLE_CONFIG_DIO_DWORD:
124 if (channel == 0) {
125 if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
126 ctrl &= ~(0x1 << instance->dio_idx);
127 } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
128 ctrl |= 0x1 << instance->dio_idx;
129 } else {
130 PERROR("Invalid port direction.\n");
131 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
132 }
133 } else {
134 PERROR("Invalid channel number.\n");
135 err = ME_ERRNO_INVALID_CHANNEL;
136 }
137 break;
138
139 default:
140 PERROR("Invalid flags.\n");
141 err = ME_ERRNO_INVALID_FLAGS;
142 }
143
144 if (!err) {
145 outl(ctrl, instance->ctrl_reg);
146 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
147 instance->reg_base,
148 instance->ctrl_reg - instance->reg_base, ctrl);
149 }
150 spin_unlock(instance->ctrl_reg_lock);
151 spin_unlock(&instance->subdevice_lock);
152
153 ME_SUBDEVICE_EXIT;
154
155 return err;
156}
157
158static int me1000_dio_io_single_read(struct me_subdevice *subdevice,
159 struct file *filep,
160 int channel,
161 int *value, int time_out, int flags)
162{
163 me1000_dio_subdevice_t *instance;
164 int err = ME_ERRNO_SUCCESS;
165
166 PDEBUG("executed.\n");
167
168 instance = (me1000_dio_subdevice_t *) subdevice;
169
170 ME_SUBDEVICE_ENTER;
171
172 spin_lock(&instance->subdevice_lock);
173 switch (flags) {
174 case ME_IO_SINGLE_TYPE_DIO_BIT:
175 if ((channel >= 0) && (channel < 32)) {
176 *value = inl(instance->port_reg) & (0x1 << channel);
177 } else {
178 PERROR("Invalid bit number.\n");
179 err = ME_ERRNO_INVALID_CHANNEL;
180 }
181 break;
182
183 case ME_IO_SINGLE_TYPE_DIO_BYTE:
184 if ((channel >= 0) && (channel < 4)) {
185 *value =
186 (inl(instance->port_reg) >> (channel * 8)) & 0xFF;
187 } else {
188 PERROR("Invalid byte number.\n");
189 err = ME_ERRNO_INVALID_CHANNEL;
190 }
191 break;
192
193 case ME_IO_SINGLE_TYPE_DIO_WORD:
194 if ((channel >= 0) && (channel < 2)) {
195 *value =
196 (inl(instance->port_reg) >> (channel * 16)) &
197 0xFFFF;
198 } else {
199 PERROR("Invalid word number.\n");
200 err = ME_ERRNO_INVALID_CHANNEL;
201 }
202 break;
203
204 case ME_IO_SINGLE_NO_FLAGS:
205 case ME_IO_SINGLE_TYPE_DIO_DWORD:
206 if (channel == 0) {
207 *value = inl(instance->port_reg);
208 } else {
209 PERROR("Invalid dword number.\n");
210 err = ME_ERRNO_INVALID_CHANNEL;
211 }
212 break;
213
214 default:
215 PERROR("Invalid flags specified.\n");
216 err = ME_ERRNO_INVALID_FLAGS;
217 }
218 spin_unlock(&instance->subdevice_lock);
219
220 ME_SUBDEVICE_EXIT;
221
222 return err;
223}
224
225static int me1000_dio_io_single_write(struct me_subdevice *subdevice,
226 struct file *filep,
227 int channel,
228 int value, int time_out, int flags)
229{
230 me1000_dio_subdevice_t *instance;
231 int err = ME_ERRNO_SUCCESS;
232 uint32_t config;
233 uint32_t state;
234
235 PDEBUG("executed.\n");
236
237 instance = (me1000_dio_subdevice_t *) subdevice;
238
239 ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
240 spin_lock(instance->ctrl_reg_lock);
241 config = inl(instance->ctrl_reg) & (0x1 << instance->dio_idx);
242 switch (flags) {
243 case ME_IO_SINGLE_TYPE_DIO_BIT:
244 if ((channel >= 0) && (channel < 32)) {
245 if (config) {
246 state = inl(instance->port_reg);
247 state =
248 value ? (state | (0x1 << channel)) : (state
249 &
250 ~(0x1
251 <<
252 channel));
253 outl(state, instance->port_reg);
254 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
255 instance->reg_base,
256 instance->port_reg -
257 instance->reg_base, state);
258 } else {
259 PERROR("Port is not in output mode.\n");
260 err = ME_ERRNO_PREVIOUS_CONFIG;
261 }
262 } else {
263 PERROR("Invalid bit number.\n");
264 err = ME_ERRNO_INVALID_CHANNEL;
265 }
266 break;
267
268 case ME_IO_SINGLE_TYPE_DIO_BYTE:
269 if ((channel >= 0) && (channel < 4)) {
270 if (config) {
271 state = inl(instance->port_reg);
272 state &= ~(0xFF << (channel * 8));
273 state |= (value & 0xFF) << (channel * 8);
274 outl(state, instance->port_reg);
275 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
276 instance->reg_base,
277 instance->port_reg -
278 instance->reg_base, state);
279 } else {
280 PERROR("Port is not in output mode.\n");
281 err = ME_ERRNO_PREVIOUS_CONFIG;
282 }
283 } else {
284 PERROR("Invalid byte number.\n");
285 err = ME_ERRNO_INVALID_CHANNEL;
286 }
287 break;
288
289 case ME_IO_SINGLE_TYPE_DIO_WORD:
290 if ((channel >= 0) && (channel < 2)) {
291 if (config) {
292 state = inl(instance->port_reg);
293 state &= ~(0xFFFF << (channel * 16));
294 state |= (value & 0xFFFF) << (channel * 16);
295 outl(state, instance->port_reg);
296 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
297 instance->reg_base,
298 instance->port_reg -
299 instance->reg_base, state);
300 } else {
301 PERROR("Port is not in output mode.\n");
302 err = ME_ERRNO_PREVIOUS_CONFIG;
303 }
304 } else {
305 PERROR("Invalid word number.\n");
306 err = ME_ERRNO_INVALID_CHANNEL;
307 }
308 break;
309
310 case ME_IO_SINGLE_NO_FLAGS:
311 case ME_IO_SINGLE_TYPE_DIO_DWORD:
312 if (channel == 0) {
313 if (config) {
314 outl(value, instance->port_reg);
315 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
316 instance->reg_base,
317 instance->port_reg -
318 instance->reg_base, value);
319 } else {
320 PERROR("Port is not in output mode.\n");
321 err = ME_ERRNO_PREVIOUS_CONFIG;
322 }
323 } else {
324 PERROR("Invalid dword number.\n");
325 err = ME_ERRNO_INVALID_CHANNEL;
326 }
327 break;
328
329 default:
330 PERROR("Invalid flags specified.\n");
331 err = ME_ERRNO_INVALID_FLAGS;
332 }
333 spin_unlock(instance->ctrl_reg_lock);
334 spin_unlock(&instance->subdevice_lock);
335
336 ME_SUBDEVICE_EXIT;
337
338 return err;
339}
340
341static int me1000_dio_query_number_channels(struct me_subdevice *subdevice,
342 int *number)
343{
344 PDEBUG("executed.\n");
345 *number = ME1000_DIO_NUMBER_CHANNELS;
346 return ME_ERRNO_SUCCESS;
347}
348
349static int me1000_dio_query_subdevice_type(struct me_subdevice *subdevice,
350 int *type, int *subtype)
351{
352 PDEBUG("executed.\n");
353 *type = ME_TYPE_DIO;
354 *subtype = ME_SUBTYPE_SINGLE;
355 return ME_ERRNO_SUCCESS;
356}
357
358static int me1000_dio_query_subdevice_caps(struct me_subdevice *subdevice,
359 int *caps)
360{
361 me1000_dio_subdevice_t *instance;
362
363 PDEBUG("executed.\n");
364
365 instance = (me1000_dio_subdevice_t *) subdevice;
366
367 *caps = ME_CAPS_DIO_DIR_DWORD;
368
369 return ME_ERRNO_SUCCESS;
370}
371
372me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base,
373 unsigned int dio_idx,
374 spinlock_t * ctrl_reg_lock)
375{
376 me1000_dio_subdevice_t *subdevice;
377 int err;
378
379 PDEBUG("executed.\n");
380
381 /* Allocate memory for subdevice instance */
382 subdevice = kmalloc(sizeof(me1000_dio_subdevice_t), GFP_KERNEL);
383
384 if (!subdevice) {
385 PERROR("Cannot get memory for ME-1000 DIO instance.\n");
386 return NULL;
387 }
388
389 memset(subdevice, 0, sizeof(me1000_dio_subdevice_t));
390
391 /* Check if counter index is out of range */
392
393 if (dio_idx >= ME1000_DIO_NUMBER_PORTS) {
394 PERROR("DIO index is out of range.\n");
395 kfree(subdevice);
396 return NULL;
397 }
398
399 /* Initialize subdevice base class */
400 err = me_subdevice_init(&subdevice->base);
401
402 if (err) {
403 PERROR("Cannot initialize subdevice base class instance.\n");
404 kfree(subdevice);
405 return NULL;
406 }
407 // Initialize spin locks.
408 spin_lock_init(&subdevice->subdevice_lock);
409 subdevice->ctrl_reg_lock = ctrl_reg_lock;
410
411 /* Save the DIO index */
412 subdevice->dio_idx = dio_idx;
413
414 /* Initialize registers. */
415#ifdef MEDEBUG_DEBUG_REG
416 subdevice->reg_base = reg_base;
417#endif
418 subdevice->ctrl_reg = reg_base + ME1000_PORT_MODE;
419 subdevice->port_reg =
420 reg_base + ME1000_PORT + (dio_idx * ME1000_PORT_STEP);
421
422 /* Override base class methods. */
423 subdevice->base.me_subdevice_io_reset_subdevice =
424 me1000_dio_io_reset_subdevice;
425 subdevice->base.me_subdevice_io_single_config =
426 me1000_dio_io_single_config;
427 subdevice->base.me_subdevice_io_single_read = me1000_dio_io_single_read;
428 subdevice->base.me_subdevice_io_single_write =
429 me1000_dio_io_single_write;
430 subdevice->base.me_subdevice_query_number_channels =
431 me1000_dio_query_number_channels;
432 subdevice->base.me_subdevice_query_subdevice_type =
433 me1000_dio_query_subdevice_type;
434 subdevice->base.me_subdevice_query_subdevice_caps =
435 me1000_dio_query_subdevice_caps;
436
437 return subdevice;
438}
diff --git a/drivers/staging/meilhaus/me1000_dio.h b/drivers/staging/meilhaus/me1000_dio.h
new file mode 100644
index 000000000000..d26e93f531af
--- /dev/null
+++ b/drivers/staging/meilhaus/me1000_dio.h
@@ -0,0 +1,71 @@
1/**
2 * @file me1000_dio.h
3 *
4 * @brief Meilhaus ME-1000 digital i/o implementation.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME1000_DIO_H_
28#define _ME1000_DIO_H_
29
30#include "mesubdevice.h"
31#include "meslock.h"
32
33#ifdef __KERNEL__
34
35/**
36 * @brief The ME-1000 DIO subdevice class.
37 */
38typedef struct me1000_dio_subdevice {
39 /* Inheritance */
40 me_subdevice_t base; /**< The subdevice base class. */
41
42 /* Attributes */
43// uint32_t magic; /**< The magic number unique for this structure. */
44
45 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
46 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg and #ctrl_reg_mirror from concurrent access. */
47 int dio_idx; /**< The index of the DIO port on the device. */
48
49 unsigned long port_reg; /**< Register to read or write a value from or to the port respectively. */
50 unsigned long ctrl_reg; /**< Register to configure the DIO modes. */
51#ifdef MEDEBUG_DEBUG_REG
52 unsigned long reg_base;
53#endif
54} me1000_dio_subdevice_t;
55
56/**
57 * @brief The constructor to generate a ME-1000 DIO instance.
58 *
59 * @param reg_base The register base address of the device as returned by the PCI BIOS.
60 * @param dio_idx The index of the DIO on the device.
61 * @param ctrl_reg_lock Pointer to spin lock protecting the control register and from concurrent access.
62 *
63 * @return Pointer to new instance on success.\n
64 * NULL on error.
65 */
66me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base,
67 unsigned int dio_idx,
68 spinlock_t * ctrl_reg_lock);
69
70#endif
71#endif
diff --git a/drivers/staging/meilhaus/me1000_dio_reg.h b/drivers/staging/meilhaus/me1000_dio_reg.h
new file mode 100644
index 000000000000..4d5b38df437f
--- /dev/null
+++ b/drivers/staging/meilhaus/me1000_dio_reg.h
@@ -0,0 +1,50 @@
1/**
2 * @file me1000_dio_reg.h
3 *
4 * @brief ME-1000 digital i/o register definitions.
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 _ME1000_DIO_REG_H_
29# define _ME1000_DIO_REG_H_
30
31# ifdef __KERNEL__
32
33# define ME1000_DIO_NUMBER_CHANNELS 32 /**< The number of channels per DIO port. */
34# define ME1000_DIO_NUMBER_PORTS 4 /**< The number of ports per ME-1000. */
35
36// # define ME1000_PORT_A 0x0000 /**< Port A base register offset. */
37// # define ME1000_PORT_B 0x0004 /**< Port B base register offset. */
38// # define ME1000_PORT_C 0x0008 /**< Port C base register offset. */
39// # define ME1000_PORT_D 0x000C /**< Port D base register offset. */
40# define ME1000_PORT 0x0000 /**< Base for port's register. */
41# define ME1000_PORT_STEP 4 /**< Distance between port's register. */
42
43# define ME1000_PORT_MODE 0x0010 /**< Configuration register to switch the port direction. */
44// # define ME1000_PORT_MODE_OUTPUT_A (1 << 0) /**< If set, port A is in output, otherwise in input mode. */
45// # define ME1000_PORT_MODE_OUTPUT_B (1 << 1) /**< If set, port B is in output, otherwise in input mode. */
46// # define ME1000_PORT_MODE_OUTPUT_C (1 << 2) /**< If set, port C is in output, otherwise in input mode. */
47// # define ME1000_PORT_MODE_OUTPUT_D (1 << 3) /**< If set, port D is in output, otherwise in input mode. */
48
49# endif //__KERNEL__
50#endif //_ME1000_DIO_REG_H_
diff --git a/drivers/staging/meilhaus/me1400_device.c b/drivers/staging/meilhaus/me1400_device.c
new file mode 100644
index 000000000000..b95bb4fce6ab
--- /dev/null
+++ b/drivers/staging/meilhaus/me1400_device.c
@@ -0,0 +1,256 @@
1/**
2 * @file me1400_device.c
3 *
4 * @brief ME-1400 device 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/*
29 * User application could also include the kernel header files. But the
30 * real kernel functions are protected by #ifdef __KERNEL__.
31 */
32#ifndef __KERNEL__
33# define __KERNEL__
34#endif
35
36/*
37 * This must be defined before module.h is included. Not needed, when
38 * it is a built in driver.
39 */
40#ifndef MODULE
41# define MODULE
42#endif
43
44#include <linux/module.h>
45
46#include <linux/pci.h>
47#include <linux/slab.h>
48#include <linux/sched.h>
49#include <linux/interrupt.h>
50#include <linux/version.h>
51
52#include "meids.h"
53#include "meerror.h"
54#include "mecommon.h"
55#include "meinternal.h"
56
57#include "medebug.h"
58
59#include "me1400_device.h"
60#include "me8254.h"
61#include "me8254_reg.h"
62#include "me8255.h"
63#include "me1400_ext_irq.h"
64
65me_device_t *me1400_pci_constructor(struct pci_dev *pci_device)
66{
67 int err;
68 me1400_device_t *me1400_device;
69 me_subdevice_t *subdevice;
70 unsigned int version_idx;
71 unsigned int me8255_idx;
72 unsigned int dio_idx;
73 unsigned int me8254_idx;
74 unsigned int ctr_idx;
75 unsigned int ext_irq_idx;
76
77 PDEBUG("executed.\n");
78
79 // Allocate structure for device instance.
80 me1400_device = kmalloc(sizeof(me1400_device_t), GFP_KERNEL);
81
82 if (!me1400_device) {
83 PERROR("Cannot get memory for 1400ate device instance.\n");
84 return NULL;
85 }
86
87 memset(me1400_device, 0, sizeof(me1400_device_t));
88
89 // Initialize base class structure.
90 err = me_device_pci_init((me_device_t *) me1400_device, pci_device);
91
92 if (err) {
93 kfree(me1400_device);
94 PERROR("Cannot initialize device base class.\n");
95 return NULL;
96 }
97
98 /* Check for ME1400 extension device. If detected we fake a ME-1400 D device id. */
99 if (me1400_device->base.info.pci.device_id ==
100 PCI_DEVICE_ID_MEILHAUS_ME140C) {
101 uint8_t ctrl;
102 ctrl =
103 inb(me1400_device->base.info.pci.reg_bases[2] +
104 ME1400D_CLK_SRC_2_REG);
105 PDEBUG_REG("xxx_reg inb(0x%X+0x%X)=0x%x\n",
106 me1400_device->base.info.pci.reg_bases[2],
107 ME1400D_CLK_SRC_2_REG, ctrl);
108 outb(ctrl | 0xF0,
109 me1400_device->base.info.pci.reg_bases[2] +
110 ME1400D_CLK_SRC_2_REG);
111 PDEBUG_REG("xxx_reg outb(0x%X+0x%X)=0x%x\n",
112 me1400_device->base.info.pci.reg_bases[2],
113 ME1400D_CLK_SRC_2_REG, ctrl | 0xF0);
114 ctrl =
115 inb(me1400_device->base.info.pci.reg_bases[2] +
116 ME1400D_CLK_SRC_2_REG);
117 PDEBUG_REG("xxx_reg inb(0x%X+0x%X)=0x%x\n",
118 me1400_device->base.info.pci.reg_bases[2],
119 ME1400D_CLK_SRC_2_REG, ctrl);
120
121 if ((ctrl & 0xF0) == 0xF0) {
122 PINFO("ME1400 D detected.\n");
123 me1400_device->base.info.pci.device_id =
124 PCI_DEVICE_ID_MEILHAUS_ME140D;
125 }
126 }
127
128 /* Initialize global stuff of digital i/o subdevices. */
129 for (me8255_idx = 0; me8255_idx < ME1400_MAX_8255; me8255_idx++) {
130 me1400_device->dio_current_mode[me8255_idx] = 0;
131 spin_lock_init(&me1400_device->dio_ctrl_reg_lock[me8255_idx]);
132 }
133
134 /* Initialize global stuff of counter subdevices. */
135 spin_lock_init(&me1400_device->clk_src_reg_lock);
136
137 for (me8254_idx = 0; me8254_idx < ME1400_MAX_8254; me8254_idx++)
138 spin_lock_init(&me1400_device->ctr_ctrl_reg_lock[me8254_idx]);
139
140 /* Get the index in the device version information table. */
141 version_idx =
142 me1400_versions_get_device_index(me1400_device->base.info.pci.
143 device_id);
144
145 /* Generate DIO subdevice instances. */
146 for (me8255_idx = 0;
147 me8255_idx < me1400_versions[version_idx].dio_chips;
148 me8255_idx++) {
149 for (dio_idx = 0; dio_idx < 3; dio_idx++) {
150 subdevice =
151 (me_subdevice_t *)
152 me8255_constructor(me1400_versions[version_idx].
153 device_id,
154 me1400_device->base.info.pci.
155 reg_bases[2], me8255_idx,
156 dio_idx,
157 &me1400_device->
158 dio_current_mode[me8255_idx],
159 &me1400_device->
160 dio_ctrl_reg_lock[me8255_idx]);
161
162 if (!subdevice) {
163 me_device_deinit((me_device_t *) me1400_device);
164 kfree(me1400_device);
165 PERROR("Cannot get memory for subdevice.\n");
166 return NULL;
167 }
168
169 me_slist_add_subdevice_tail(&me1400_device->base.slist,
170 subdevice);
171 }
172 }
173
174 /* Generate counter subdevice instances. */
175 for (me8254_idx = 0;
176 me8254_idx < me1400_versions[version_idx].ctr_chips;
177 me8254_idx++) {
178 for (ctr_idx = 0; ctr_idx < 3; ctr_idx++) {
179 subdevice =
180 (me_subdevice_t *)
181 me8254_constructor(me1400_device->base.info.pci.
182 device_id,
183 me1400_device->base.info.pci.
184 reg_bases[2], me8254_idx,
185 ctr_idx,
186 &me1400_device->
187 ctr_ctrl_reg_lock[me8254_idx],
188 &me1400_device->
189 clk_src_reg_lock);
190
191 if (!subdevice) {
192 me_device_deinit((me_device_t *) me1400_device);
193 kfree(me1400_device);
194 PERROR("Cannot get memory for subdevice.\n");
195 return NULL;
196 }
197
198 me_slist_add_subdevice_tail(&me1400_device->base.slist,
199 subdevice);
200 }
201 }
202
203 /* Generate external interrupt subdevice instances. */
204 for (ext_irq_idx = 0;
205 ext_irq_idx < me1400_versions[version_idx].ext_irq_subdevices;
206 ext_irq_idx++) {
207 subdevice =
208 (me_subdevice_t *)
209 me1400_ext_irq_constructor(me1400_device->base.info.pci.
210 device_id,
211 me1400_device->base.info.pci.
212 reg_bases[1],
213 me1400_device->base.info.pci.
214 reg_bases[2],
215 &me1400_device->clk_src_reg_lock,
216 me1400_device->base.irq);
217
218 if (!subdevice) {
219 me_device_deinit((me_device_t *) me1400_device);
220 kfree(me1400_device);
221 PERROR("Cannot get memory for subdevice.\n");
222 return NULL;
223 }
224
225 me_slist_add_subdevice_tail(&me1400_device->base.slist,
226 subdevice);
227 }
228
229 return (me_device_t *) me1400_device;
230}
231
232// Init and exit of module.
233
234static int __init me1400_init(void)
235{
236 PDEBUG("executed.\n");
237 return 0;
238}
239
240static void __exit me1400_exit(void)
241{
242 PDEBUG("executed.\n");
243}
244
245module_init(me1400_init);
246module_exit(me1400_exit);
247
248// Administrative stuff for modinfo.
249MODULE_AUTHOR
250 ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
251MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-14xx devices");
252MODULE_SUPPORTED_DEVICE("Meilhaus ME-14xx MIO devices");
253MODULE_LICENSE("GPL");
254
255// Export the constructor.
256EXPORT_SYMBOL(me1400_pci_constructor);
diff --git a/drivers/staging/meilhaus/me1400_device.h b/drivers/staging/meilhaus/me1400_device.h
new file mode 100644
index 000000000000..6215b250047d
--- /dev/null
+++ b/drivers/staging/meilhaus/me1400_device.h
@@ -0,0 +1,108 @@
1/**
2 * @file me1400_device.c
3 *
4 * @brief ME-1400 device family instance.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME1400_DEVICE_H_
28#define _ME1400_DEVICE_H_
29
30#include "metypes.h"
31#include "medefines.h"
32#include "meinternal.h"
33
34#include "medevice.h"
35
36#ifdef __KERNEL__
37
38/**
39 * @brief Structure to store device capabilities.
40 */
41typedef struct me1400_version {
42 uint16_t device_id; /**< The PCI device id of the device. */
43 unsigned int dio_chips; /**< The number of 8255 chips on the device. */
44 unsigned int ctr_chips; /**< The number of 8254 chips on the device. */
45 unsigned int ext_irq_subdevices; /**< The number of external interrupt inputs on the device. */
46} me1400_version_t;
47
48/**
49 * @brief Defines for each ME-1400 device version its capabilities.
50 */
51static me1400_version_t me1400_versions[] = {
52 {PCI_DEVICE_ID_MEILHAUS_ME1400, 1, 0, 0},
53 {PCI_DEVICE_ID_MEILHAUS_ME140A, 1, 1, 1},
54 {PCI_DEVICE_ID_MEILHAUS_ME140B, 2, 2, 1},
55 {PCI_DEVICE_ID_MEILHAUS_ME14E0, 1, 0, 0},
56 {PCI_DEVICE_ID_MEILHAUS_ME14EA, 1, 1, 1},
57 {PCI_DEVICE_ID_MEILHAUS_ME14EB, 2, 2, 1},
58 {PCI_DEVICE_ID_MEILHAUS_ME140C, 1, 5, 1},
59 {PCI_DEVICE_ID_MEILHAUS_ME140D, 2, 10, 1},
60 {0}
61};
62
63#define ME1400_DEVICE_VERSIONS (sizeof(me1400_versions) / sizeof(me1400_version_t) - 1) /**< Returns the number of entries in #me1400_versions. */
64
65/**
66 * @brief Returns the index of the device entry in #me1400_versions.
67 *
68 * @param device_id The PCI device id of the device to query.
69 * @return The index of the device in #me1400_versions.
70 */
71static inline unsigned int me1400_versions_get_device_index(uint16_t device_id)
72{
73 unsigned int i;
74 for (i = 0; i < ME1400_DEVICE_VERSIONS; i++)
75 if (me1400_versions[i].device_id == device_id)
76 break;
77 return i;
78}
79
80#define ME1400_MAX_8254 10 /**< The maximum number of 8254 counter subdevices available on any ME-1400 device. */
81#define ME1400_MAX_8255 2 /**< The maximum number of 8255 digital i/o subdevices available on any ME-1400 device. */
82
83/**
84 * @brief The ME-1400 device class.
85 */
86typedef struct me1400_device {
87 me_device_t base; /**< The Meilhaus device base class. */
88
89 spinlock_t clk_src_reg_lock; /**< Guards the 8254 clock source registers. */
90 spinlock_t ctr_ctrl_reg_lock[ME1400_MAX_8254]; /**< Guards the 8254 ctrl registers. */
91
92 int dio_current_mode[ME1400_MAX_8255]; /**< Saves the current mode setting of a single 8255 DIO chip. */
93 spinlock_t dio_ctrl_reg_lock[ME1400_MAX_8255]; /**< Guards the 8255 ctrl register and #dio_current_mode. */
94} me1400_device_t;
95
96/**
97 * @brief The ME-1400 device class constructor.
98 *
99 * @param pci_device The pci device structure given by the PCI subsystem.
100 *
101 * @return On succes a new ME-1400 device instance. \n
102 * NULL on error.
103 */
104me_device_t *me1400_pci_constructor(struct pci_dev *pci_device)
105 __attribute__ ((weak));
106
107#endif
108#endif
diff --git a/drivers/staging/meilhaus/me1400_ext_irq.c b/drivers/staging/meilhaus/me1400_ext_irq.c
new file mode 100644
index 000000000000..b8c2696bc150
--- /dev/null
+++ b/drivers/staging/meilhaus/me1400_ext_irq.c
@@ -0,0 +1,517 @@
1/**
2 * @file me1400_ext_irq.c
3 *
4 * @brief ME-1400 external interrupt 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/version.h>
36#include <linux/module.h>
37
38#include <linux/slab.h>
39#include <linux/spinlock.h>
40#include <asm/io.h>
41#include <linux/types.h>
42#include <linux/interrupt.h>
43
44#include "medefines.h"
45#include "meinternal.h"
46#include "meerror.h"
47#include "medebug.h"
48#include "meids.h"
49
50#include "me1400_ext_irq.h"
51#include "me1400_ext_irq_reg.h"
52
53/*
54 * Defines
55 */
56#define ME1400_EXT_IRQ_MAGIC_NUMBER 0x1401 /**< The magic number of the class structure. */
57#define ME1400_EXT_IRQ_NUMBER_CHANNELS 1 /**< One channel per counter. */
58
59/*
60 * Functions
61 */
62
63static int me1400_ext_irq_io_irq_start(struct me_subdevice *subdevice,
64 struct file *filep,
65 int channel,
66 int irq_source,
67 int irq_edge, int irq_arg, int flags)
68{
69 me1400_ext_irq_subdevice_t *instance;
70 unsigned long cpu_flags;
71 uint8_t tmp;
72
73 PDEBUG("executed.\n");
74
75 instance = (me1400_ext_irq_subdevice_t *) subdevice;
76
77 if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
78 PERROR("Invalid flag specified.\n");
79 return ME_ERRNO_INVALID_FLAGS;
80 }
81
82 if (channel) {
83 PERROR("Invalid channel.\n");
84 return ME_ERRNO_INVALID_CHANNEL;
85 }
86
87 if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
88 PERROR("Invalid irq source.\n");
89 return ME_ERRNO_INVALID_IRQ_SOURCE;
90 }
91
92 if (irq_edge != ME_IRQ_EDGE_RISING) {
93 PERROR("Invalid irq edge.\n");
94 return ME_ERRNO_INVALID_IRQ_EDGE;
95 }
96
97 ME_SUBDEVICE_ENTER;
98
99 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
100
101 spin_lock(instance->clk_src_reg_lock);
102// // Enable IRQ on PLX
103// tmp = inb(instance->plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN);
104// outb(tmp, instance->plx_intcs_reg);
105// PDEBUG_REG("ctrl_reg outb(PLX:0x%lX)=0x%x\n", instance->plx_intcs_reg, tmp);
106
107 // Enable IRQ
108 switch (instance->device_id) {
109 case PCI_DEVICE_ID_MEILHAUS_ME140C:
110 case PCI_DEVICE_ID_MEILHAUS_ME140D:
111 tmp = inb(instance->ctrl_reg);
112 tmp |= ME1400CD_EXT_IRQ_CLK_EN;
113 outb(tmp, instance->ctrl_reg);
114 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
115 instance->reg_base,
116 instance->ctrl_reg - instance->reg_base, tmp);
117 break;
118
119 default:
120 outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg);
121 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
122 instance->reg_base,
123 instance->ctrl_reg - instance->reg_base,
124 ME1400AB_EXT_IRQ_IRQ_EN);
125 break;
126 }
127 spin_unlock(instance->clk_src_reg_lock);
128 instance->rised = 0;
129 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
130
131 ME_SUBDEVICE_EXIT;
132
133 return ME_ERRNO_SUCCESS;
134}
135
136static int me1400_ext_irq_io_irq_wait(struct me_subdevice *subdevice,
137 struct file *filep,
138 int channel,
139 int *irq_count,
140 int *value, int time_out, int flags)
141{
142 me1400_ext_irq_subdevice_t *instance;
143 unsigned long cpu_flags;
144 long t = 0;
145 int err = ME_ERRNO_SUCCESS;
146
147 PDEBUG("executed.\n");
148
149 instance = (me1400_ext_irq_subdevice_t *) subdevice;
150
151 if (flags) {
152 PERROR("Invalid flag specified.\n");
153 return ME_ERRNO_INVALID_FLAGS;
154 }
155
156 if (channel) {
157 PERROR("Invalid channel.\n");
158 return ME_ERRNO_INVALID_CHANNEL;
159 }
160
161 if (time_out < 0) {
162 PERROR("Invalid time out.\n");
163 return ME_ERRNO_INVALID_TIMEOUT;
164 }
165
166 if (time_out) {
167 /* Convert to ticks */
168 t = (time_out * HZ) / 1000;
169
170 if (t == 0)
171 t = 1;
172 }
173
174 ME_SUBDEVICE_ENTER;
175
176 if (instance->rised <= 0) {
177 instance->rised = 0;
178 if (time_out) {
179 t = wait_event_interruptible_timeout(instance->
180 wait_queue,
181 (instance->rised !=
182 0), t);
183
184 if (t == 0) {
185 PERROR("Wait on interrupt timed out.\n");
186 err = ME_ERRNO_TIMEOUT;
187 }
188 } else {
189 wait_event_interruptible(instance->wait_queue,
190 (instance->rised != 0));
191 }
192
193 if (instance->rised < 0) {
194 PERROR("Wait on interrupt aborted by user.\n");
195 err = ME_ERRNO_CANCELLED;
196 }
197 }
198
199 if (signal_pending(current)) {
200 PERROR("Wait on interrupt aborted by signal.\n");
201 err = ME_ERRNO_SIGNAL;
202 }
203
204 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
205 instance->rised = 0;
206 *irq_count = instance->n;
207 *value = 1;
208 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
209
210 ME_SUBDEVICE_EXIT;
211
212 return err;
213}
214
215static int me1400_ext_irq_io_irq_stop(struct me_subdevice *subdevice,
216 struct file *filep,
217 int channel, int flags)
218{
219 me1400_ext_irq_subdevice_t *instance;
220 unsigned long cpu_flags;
221 uint8_t tmp;
222 int err = ME_ERRNO_SUCCESS;
223
224 PDEBUG("executed.\n");
225
226 instance = (me1400_ext_irq_subdevice_t *) subdevice;
227
228 if (flags) {
229 PERROR("Invalid flag specified.\n");
230 return ME_ERRNO_INVALID_FLAGS;
231 }
232
233 if (channel) {
234 PERROR("Invalid channel.\n");
235 return ME_ERRNO_INVALID_CHANNEL;
236 }
237
238 ME_SUBDEVICE_ENTER;
239
240 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
241 spin_lock(instance->clk_src_reg_lock);
242// // Disable IRQ on PLX
243// tmp = inb(instance->plx_intcs_reg) & ( ~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN));
244// outb(tmp, instance->plx_intcs_reg);
245// PDEBUG_REG("ctrl_reg outb(PLX:0x%lX)=0x%x\n", instance->plx_intcs_reg, tmp);
246
247 switch (instance->device_id) {
248 case PCI_DEVICE_ID_MEILHAUS_ME140C:
249 case PCI_DEVICE_ID_MEILHAUS_ME140D:
250 tmp = inb(instance->ctrl_reg);
251 tmp &= ~ME1400CD_EXT_IRQ_CLK_EN;
252 outb(tmp, instance->ctrl_reg);
253 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
254 instance->reg_base,
255 instance->ctrl_reg - instance->reg_base, tmp);
256
257 break;
258
259 default:
260 outb(0x00, instance->ctrl_reg);
261 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
262 instance->reg_base,
263 instance->ctrl_reg - instance->reg_base, 0x00);
264 break;
265 }
266 spin_unlock(instance->clk_src_reg_lock);
267 instance->rised = -1;
268 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
269 wake_up_interruptible_all(&instance->wait_queue);
270
271 ME_SUBDEVICE_EXIT;
272
273 return err;
274}
275
276static int me1400_ext_irq_io_reset_subdevice(struct me_subdevice *subdevice,
277 struct file *filep, int flags)
278{
279 me1400_ext_irq_subdevice_t *instance =
280 (me1400_ext_irq_subdevice_t *) subdevice;
281
282 PDEBUG("executed.\n");
283
284 if (flags) {
285 PERROR("Invalid flag specified.\n");
286 return ME_ERRNO_INVALID_FLAGS;
287 }
288
289 instance->n = 0;
290 return me1400_ext_irq_io_irq_stop(subdevice, filep, 0, flags);
291}
292
293static int me1400_ext_irq_query_number_channels(struct me_subdevice *subdevice,
294 int *number)
295{
296 PDEBUG("executed.\n");
297 *number = ME1400_EXT_IRQ_NUMBER_CHANNELS;
298 return ME_ERRNO_SUCCESS;
299}
300
301static int me1400_ext_irq_query_subdevice_type(struct me_subdevice *subdevice,
302 int *type, int *subtype)
303{
304 PDEBUG("executed.\n");
305 *type = ME_TYPE_EXT_IRQ;
306 *subtype = ME_SUBTYPE_SINGLE;
307 return ME_ERRNO_SUCCESS;
308}
309
310static int me1400_ext_irq_query_subdevice_caps(struct me_subdevice *subdevice,
311 int *caps)
312{
313 PDEBUG("executed.\n");
314 *caps = ME_CAPS_EXT_IRQ_EDGE_RISING;
315 return ME_ERRNO_SUCCESS;
316}
317
318static int me1400_ext_irq_query_subdevice_caps_args(struct me_subdevice
319 *subdevice, int cap,
320 int *args, int count)
321{
322 PDEBUG("executed.\n");
323 return ME_ERRNO_NOT_SUPPORTED;
324}
325
326#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
327static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id)
328#else
329static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id,
330 struct pt_regs *regs)
331#endif
332{
333 me1400_ext_irq_subdevice_t *instance;
334 uint32_t status;
335 uint8_t tmp;
336
337 instance = (me1400_ext_irq_subdevice_t *) dev_id;
338
339 if (irq != instance->irq) {
340 PERROR("Incorrect interrupt num: %d.\n", irq);
341 return IRQ_NONE;
342 }
343
344 spin_lock(&instance->subdevice_lock);
345 status = inl(instance->plx_intcs_reg);
346// if (!((status & PLX_LOCAL_INT1_STATE) && (status & PLX_LOCAL_INT1_EN) && (status & PLX_PCI_INT_EN)))
347 if ((status &
348 (PLX_LOCAL_INT1_STATE | PLX_LOCAL_INT1_EN | PLX_PCI_INT_EN)) !=
349 (PLX_LOCAL_INT1_STATE | PLX_LOCAL_INT1_EN | PLX_PCI_INT_EN)) {
350 spin_unlock(&instance->subdevice_lock);
351 PINFO("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n",
352 jiffies, __FUNCTION__, status);
353 return IRQ_NONE;
354 }
355
356 inl(instance->ctrl_reg);
357
358 PDEBUG("executed.\n");
359
360 instance->n++;
361 instance->rised = 1;
362
363 switch (instance->device_id) {
364
365 case PCI_DEVICE_ID_MEILHAUS_ME140C:
366 case PCI_DEVICE_ID_MEILHAUS_ME140D:
367 spin_lock(instance->clk_src_reg_lock);
368 tmp = inb(instance->ctrl_reg);
369 tmp &= ~ME1400CD_EXT_IRQ_CLK_EN;
370 outb(tmp, instance->ctrl_reg);
371 PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
372 instance->reg_base,
373 instance->ctrl_reg - instance->reg_base, tmp);
374 tmp |= ME1400CD_EXT_IRQ_CLK_EN;
375 outb(tmp, instance->ctrl_reg);
376 PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
377 instance->reg_base,
378 instance->ctrl_reg - instance->reg_base, tmp);
379 spin_unlock(instance->clk_src_reg_lock);
380
381 break;
382
383 default:
384 outb(0, instance->ctrl_reg);
385 PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
386 instance->reg_base,
387 instance->ctrl_reg - instance->reg_base, 0);
388 outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg);
389 PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
390 instance->reg_base,
391 instance->ctrl_reg - instance->reg_base,
392 ME1400AB_EXT_IRQ_IRQ_EN);
393 break;
394 }
395
396 spin_unlock(&instance->subdevice_lock);
397 wake_up_interruptible_all(&instance->wait_queue);
398
399 return IRQ_HANDLED;
400}
401
402static void me1400_ext_irq_destructor(struct me_subdevice *subdevice)
403{
404 me1400_ext_irq_subdevice_t *instance;
405 uint8_t tmp;
406
407 PDEBUG("executed.\n");
408
409 instance = (me1400_ext_irq_subdevice_t *) subdevice;
410
411 // Disable IRQ on PLX
412 tmp =
413 inb(instance->
414 plx_intcs_reg) & (~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL |
415 PLX_PCI_INT_EN));
416 outb(tmp, instance->plx_intcs_reg);
417 PDEBUG_REG("ctrl_reg outb(plx:0x%lX)=0x%x\n", instance->plx_intcs_reg,
418 tmp);
419
420 free_irq(instance->irq, (void *)instance);
421 me_subdevice_deinit(&instance->base);
422 kfree(instance);
423}
424
425me1400_ext_irq_subdevice_t *me1400_ext_irq_constructor(uint32_t device_id,
426 uint32_t plx_reg_base,
427 uint32_t me1400_reg_base,
428 spinlock_t *
429 clk_src_reg_lock,
430 int irq)
431{
432 me1400_ext_irq_subdevice_t *subdevice;
433 int err;
434 uint8_t tmp;
435
436 PDEBUG("executed.\n");
437
438 /* Allocate memory for subdevice instance */
439 subdevice = kmalloc(sizeof(me1400_ext_irq_subdevice_t), GFP_KERNEL);
440
441 if (!subdevice) {
442 PERROR("Cannot get memory for 1400_ext_irq instance.\n");
443 return NULL;
444 }
445
446 memset(subdevice, 0, sizeof(me1400_ext_irq_subdevice_t));
447
448 /* Initialize subdevice base class */
449 err = me_subdevice_init(&subdevice->base);
450
451 if (err) {
452 PERROR("Cannot initialize subdevice base class instance.\n");
453 kfree(subdevice);
454 return NULL;
455 }
456 // Initialize spin locks.
457 spin_lock_init(&subdevice->subdevice_lock);
458 subdevice->clk_src_reg_lock = clk_src_reg_lock;
459
460 /* Initialize wait queue */
461 init_waitqueue_head(&subdevice->wait_queue);
462
463 subdevice->irq = irq;
464
465 err = request_irq(irq, me1400_ext_irq_isr,
466#ifdef IRQF_DISABLED
467 IRQF_DISABLED | IRQF_SHARED,
468#else
469 SA_INTERRUPT | SA_SHIRQ,
470#endif
471 ME1400_NAME, (void *)subdevice);
472
473 if (err) {
474 PERROR("Can't get irq.\n");
475 me_subdevice_deinit(&subdevice->base);
476 kfree(subdevice);
477 return NULL;
478 }
479 PINFO("Registered irq=%d.\n", subdevice->irq);
480
481 /* Initialize registers */
482 subdevice->plx_intcs_reg = plx_reg_base + PLX_INTCSR_REG;
483 subdevice->ctrl_reg = me1400_reg_base + ME1400AB_EXT_IRQ_CTRL_REG;
484#ifdef MEDEBUG_DEBUG_REG
485 subdevice->reg_base = me1400_reg_base;
486#endif
487
488 // Enable IRQ on PLX
489 tmp =
490 inb(subdevice->
491 plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL |
492 PLX_PCI_INT_EN);
493 outb(tmp, subdevice->plx_intcs_reg);
494 PDEBUG_REG("ctrl_reg outb(Pplx:0x%lX)=0x%x\n", subdevice->plx_intcs_reg,
495 tmp);
496
497 /* Initialize the subdevice methods */
498 subdevice->base.me_subdevice_io_irq_start = me1400_ext_irq_io_irq_start;
499 subdevice->base.me_subdevice_io_irq_wait = me1400_ext_irq_io_irq_wait;
500 subdevice->base.me_subdevice_io_irq_stop = me1400_ext_irq_io_irq_stop;
501 subdevice->base.me_subdevice_io_reset_subdevice =
502 me1400_ext_irq_io_reset_subdevice;
503 subdevice->base.me_subdevice_query_number_channels =
504 me1400_ext_irq_query_number_channels;
505 subdevice->base.me_subdevice_query_subdevice_type =
506 me1400_ext_irq_query_subdevice_type;
507 subdevice->base.me_subdevice_query_subdevice_caps =
508 me1400_ext_irq_query_subdevice_caps;
509 subdevice->base.me_subdevice_query_subdevice_caps_args =
510 me1400_ext_irq_query_subdevice_caps_args;
511 subdevice->base.me_subdevice_destructor = me1400_ext_irq_destructor;
512
513 subdevice->rised = 0;
514 subdevice->n = 0;
515
516 return subdevice;
517}
diff --git a/drivers/staging/meilhaus/me1400_ext_irq.h b/drivers/staging/meilhaus/me1400_ext_irq.h
new file mode 100644
index 000000000000..9b72a04701c0
--- /dev/null
+++ b/drivers/staging/meilhaus/me1400_ext_irq.h
@@ -0,0 +1,62 @@
1/**
2 * @file me1400_ext_irq.h
3 *
4 * @brief ME-1400 external interrupt implementation.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _ME1400_EXT_IRQ_H_
10#define _ME1400_EXT_IRQ_H_
11
12#include <linux/sched.h>
13
14#include "mesubdevice.h"
15#include "meslock.h"
16
17#ifdef __KERNEL__
18
19/**
20 * @brief The ME-1400 external interrupt subdevice class.
21 */
22typedef struct me1400_ext_irq_subdevice {
23 /* Inheritance */
24 me_subdevice_t base; /**< The subdevice base class. */
25
26 /* Attributes */
27 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
28 spinlock_t *clk_src_reg_lock; /**< Lock protecting the clock control register. */
29
30 wait_queue_head_t wait_queue; /**< Queue to put on threads waiting for an interrupt. */
31
32 uint32_t device_id; /**< The device id of the device holding the subdevice. */
33 int irq; /**< The irq number assigned by PCI BIOS. */
34 int rised; /**< If true an interrupt has occured. */
35 unsigned int n; /**< The number of interrupt since the driver was loaded. */
36
37 unsigned long plx_intcs_reg; /**< The PLX interrupt control and status register. */
38 unsigned long ctrl_reg; /**< The control register. */
39#ifdef MEDEBUG_DEBUG_REG
40 unsigned long reg_base;
41#endif
42} me1400_ext_irq_subdevice_t;
43
44/**
45 * @brief The constructor to generate a ME-1400 external interrupt instance.
46 *
47 * @param plx_reg_base The register base address of the PLX chip as returned by the PCI BIOS.
48 * @param me1400_reg_base The register base address of the ME-1400 device as returned by the PCI BIOS.
49 * @param irq The irq assigned by the PCI BIOS.
50 *
51 * @return Pointer to new instance on success.\n
52 * NULL on error.
53 */
54me1400_ext_irq_subdevice_t *me1400_ext_irq_constructor(uint32_t device_id,
55 uint32_t plx_reg_base,
56 uint32_t me1400_reg_base,
57 spinlock_t *
58 clk_src_reg_lock,
59 int irq);
60
61#endif
62#endif
diff --git a/drivers/staging/meilhaus/me1400_ext_irq_reg.h b/drivers/staging/meilhaus/me1400_ext_irq_reg.h
new file mode 100644
index 000000000000..c9740f2dd3a7
--- /dev/null
+++ b/drivers/staging/meilhaus/me1400_ext_irq_reg.h
@@ -0,0 +1,56 @@
1/**
2 * @file me1400_ext_irq_reg.h
3 *
4 * @brief ME-1400 external interrupt register definitions.
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 _ME1400_EXT_IRQ_REG_H_
29# define _ME1400_EXT_IRQ_REG_H_
30
31# ifdef __KERNEL__
32
33# define PLX_INTCSR_REG 0x4C /**< The PLX interrupt control and status register offset. */
34# define PLX_ICR_REG 0x50 /**< The PLX initialization control register offset. */
35
36# define PLX_LOCAL_INT1_EN 0x01 /**< If set the local interrupt 1 is enabled. */
37# define PLX_LOCAL_INT1_POL 0x02 /**< If set the local interrupt 1 polarity is high active. */
38# define PLX_LOCAL_INT1_STATE 0x04 /**< If set the local interrupt 1 is activ. */
39# define PLX_LOCAL_INT2_EN 0x08 /**< If set the local interrupt 2 is enabled. */
40# define PLX_LOCAL_INT2_POL 0x10 /**< If set the local interrupt 2 polarity is high active. */
41# define PLX_LOCAL_INT2_STATE 0x20 /**< If set the local interrupt 2 is activ. */
42# define PLX_PCI_INT_EN 0x40 /**< If set the PCI interrupt is enabled. */
43# define PLX_SOFT_INT 0x80 /**< If set an interrupt is generated. */
44
45# define ME1400AB_EXT_IRQ_CTRL_REG 0x11 /**< The external interrupt control register offset. */
46
47# define ME1400AB_EXT_IRQ_CLK_EN 0x01 /**< If this bit is set, the clock output is enabled. */
48# define ME1400AB_EXT_IRQ_IRQ_EN 0x02 /**< If set the external interrupt is enabled. Clearing this bit clears a pending interrupt. */
49
50# define ME1400CD_EXT_IRQ_CTRL_REG 0x11 /**< The external interrupt control register offset. */
51
52# define ME1400CD_EXT_IRQ_CLK_EN 0x10 /**< If set the external interrupt is enabled. Clearing this bit clears a pending interrupt.*/
53
54# endif //__KERNEL__
55
56#endif //_ME1400_EXT_IRQ_REG_H_
diff --git a/drivers/staging/meilhaus/me1600_ao.c b/drivers/staging/meilhaus/me1600_ao.c
new file mode 100644
index 000000000000..6f26665b30b7
--- /dev/null
+++ b/drivers/staging/meilhaus/me1600_ao.c
@@ -0,0 +1,1033 @@
1/**
2 * @file me1600_ao.c
3 *
4 * @brief ME-1600 analog output 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 */
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/sched.h>
42
43#include <linux/workqueue.h>
44
45#include "medefines.h"
46#include "meinternal.h"
47#include "meerror.h"
48#include "medebug.h"
49
50#include "me1600_ao_reg.h"
51#include "me1600_ao.h"
52
53/* Defines
54 */
55
56static void me1600_ao_destructor(struct me_subdevice *subdevice);
57
58#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
59static void me1600_ao_work_control_task(void *subdevice);
60#else
61static void me1600_ao_work_control_task(struct work_struct *work);
62#endif
63
64static int me1600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
65 struct file *filep, int flags);
66static int me1600_ao_io_single_config(me_subdevice_t * subdevice,
67 struct file *filep, int channel,
68 int single_config, int ref, int trig_chan,
69 int trig_type, int trig_edge, int flags);
70static int me1600_ao_io_single_read(me_subdevice_t * subdevice,
71 struct file *filep, int channel, int *value,
72 int time_out, int flags);
73static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
74 struct file *filep, int channel, int value,
75 int time_out, int flags);
76static int me1600_ao_query_number_channels(me_subdevice_t * subdevice,
77 int *number);
78static int me1600_ao_query_subdevice_type(me_subdevice_t * subdevice, int *type,
79 int *subtype);
80static int me1600_ao_query_subdevice_caps(me_subdevice_t * subdevice,
81 int *caps);
82static int me1600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
83 int unit, int *min, int *max,
84 int *maxdata, int *range);
85static int me1600_ao_query_number_ranges(me_subdevice_t * subdevice, int unit,
86 int *count);
87static int me1600_ao_query_range_info(me_subdevice_t * subdevice, int range,
88 int *unit, int *min, int *max,
89 int *maxdata);
90
91/* Functions
92 */
93
94me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base,
95 unsigned int ao_idx,
96 int curr,
97 spinlock_t * config_regs_lock,
98 spinlock_t * ao_shadows_lock,
99 me1600_ao_shadow_t *
100 ao_regs_shadows,
101 struct workqueue_struct *me1600_wq)
102{
103 me1600_ao_subdevice_t *subdevice;
104 int err;
105
106 PDEBUG("executed. idx=%d\n", ao_idx);
107
108 // Allocate memory for subdevice instance.
109 subdevice = kmalloc(sizeof(me1600_ao_subdevice_t), GFP_KERNEL);
110
111 if (!subdevice) {
112 PERROR
113 ("Cannot get memory for analog output subdevice instance.\n");
114 return NULL;
115 }
116
117 memset(subdevice, 0, sizeof(me1600_ao_subdevice_t));
118
119 // Initialize subdevice base class.
120 err = me_subdevice_init(&subdevice->base);
121
122 if (err) {
123 PERROR("Cannot initialize subdevice base class instance.\n");
124 kfree(subdevice);
125 return NULL;
126 }
127 // Initialize spin locks.
128 spin_lock_init(&subdevice->subdevice_lock);
129 subdevice->config_regs_lock = config_regs_lock;
130 subdevice->ao_shadows_lock = ao_shadows_lock;
131
132 // Save the subdevice index.
133 subdevice->ao_idx = ao_idx;
134
135 // Initialize range lists.
136 subdevice->u_ranges_count = 2;
137
138 subdevice->u_ranges[0].min = 0; //0V
139 subdevice->u_ranges[0].max = 9997558; //10V
140
141 subdevice->u_ranges[1].min = -10E6; //-10V
142 subdevice->u_ranges[1].max = 9995117; //10V
143
144 if (curr) { // This is version with current outputs.
145 subdevice->i_ranges_count = 2;
146
147 subdevice->i_ranges[0].min = 0; //0mA
148 subdevice->i_ranges[0].max = 19995117; //20mA
149
150 subdevice->i_ranges[1].min = 4E3; //4mA
151 subdevice->i_ranges[1].max = 19995118; //20mA
152 } else { // This is version without current outputs.
153 subdevice->i_ranges_count = 0;
154
155 subdevice->i_ranges[0].min = 0; //0mA
156 subdevice->i_ranges[0].max = 0; //0mA
157
158 subdevice->i_ranges[1].min = 0; //0mA
159 subdevice->i_ranges[1].max = 0; //0mA
160 }
161
162 // Initialize registers.
163 subdevice->uni_bi_reg = reg_base + ME1600_UNI_BI_REG;
164 subdevice->i_range_reg = reg_base + ME1600_020_420_REG;
165 subdevice->sim_output_reg = reg_base + ME1600_SIM_OUTPUT_REG;
166 subdevice->current_on_reg = reg_base + ME1600_CURRENT_ON_REG;
167#ifdef MEDEBUG_DEBUG_REG
168 subdevice->reg_base = reg_base;
169#endif
170
171 // Initialize shadow structure.
172 subdevice->ao_regs_shadows = ao_regs_shadows;
173
174 // Override base class methods.
175 subdevice->base.me_subdevice_destructor = me1600_ao_destructor;
176 subdevice->base.me_subdevice_io_reset_subdevice =
177 me1600_ao_io_reset_subdevice;
178 subdevice->base.me_subdevice_io_single_config =
179 me1600_ao_io_single_config;
180 subdevice->base.me_subdevice_io_single_read = me1600_ao_io_single_read;
181 subdevice->base.me_subdevice_io_single_write =
182 me1600_ao_io_single_write;
183 subdevice->base.me_subdevice_query_number_channels =
184 me1600_ao_query_number_channels;
185 subdevice->base.me_subdevice_query_subdevice_type =
186 me1600_ao_query_subdevice_type;
187 subdevice->base.me_subdevice_query_subdevice_caps =
188 me1600_ao_query_subdevice_caps;
189 subdevice->base.me_subdevice_query_range_by_min_max =
190 me1600_ao_query_range_by_min_max;
191 subdevice->base.me_subdevice_query_number_ranges =
192 me1600_ao_query_number_ranges;
193 subdevice->base.me_subdevice_query_range_info =
194 me1600_ao_query_range_info;
195
196 // Initialize wait queue.
197 init_waitqueue_head(&subdevice->wait_queue);
198
199 // Prepare work queue.
200 subdevice->me1600_workqueue = me1600_wq;
201
202/* workqueue API changed in kernel 2.6.20 */
203#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
204 INIT_WORK(&subdevice->ao_control_task, me1600_ao_work_control_task,
205 (void *)subdevice);
206#else
207 INIT_DELAYED_WORK(&subdevice->ao_control_task,
208 me1600_ao_work_control_task);
209#endif
210 return subdevice;
211}
212
213static void me1600_ao_destructor(struct me_subdevice *subdevice)
214{
215 me1600_ao_subdevice_t *instance;
216
217 instance = (me1600_ao_subdevice_t *) subdevice;
218
219 PDEBUG("executed. idx=%d\n", instance->ao_idx);
220
221 instance->ao_control_task_flag = 0;
222
223 // Reset subdevice to asure clean exit.
224 me1600_ao_io_reset_subdevice(subdevice, NULL,
225 ME_IO_RESET_SUBDEVICE_NO_FLAGS);
226
227 // Remove any tasks from work queue. This is paranoic because it was done allready in reset().
228 if (!cancel_delayed_work(&instance->ao_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue.
229 set_current_state(TASK_INTERRUPTIBLE);
230 schedule_timeout(2);
231 }
232}
233
234static int me1600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
235 struct file *filep, int flags)
236{
237 me1600_ao_subdevice_t *instance;
238 uint16_t tmp;
239
240 instance = (me1600_ao_subdevice_t *) subdevice;
241
242 PDEBUG("executed. idx=%d\n", instance->ao_idx);
243
244 if (flags) {
245 PERROR("Invalid flag specified.\n");
246 return ME_ERRNO_INVALID_FLAGS;
247 }
248
249 ME_SUBDEVICE_ENTER;
250
251 //Cancel control task
252 PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
253 instance->ao_control_task_flag = 0;
254 cancel_delayed_work(&instance->ao_control_task);
255 (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Cancell waiting for trigger.
256
257 // Reset all settings.
258 spin_lock(&instance->subdevice_lock);
259 spin_lock(instance->ao_shadows_lock);
260 (instance->ao_regs_shadows)->shadow[instance->ao_idx] = 0;
261 (instance->ao_regs_shadows)->mirror[instance->ao_idx] = 0;
262 (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Not waiting for triggering.
263 (instance->ao_regs_shadows)->synchronous &= ~(0x1 << instance->ao_idx); //Individual triggering.
264
265 // Set output to default (safe) state.
266 spin_lock(instance->config_regs_lock);
267 tmp = inw(instance->uni_bi_reg); // unipolar
268 tmp |= (0x1 << instance->ao_idx);
269 outw(tmp, instance->uni_bi_reg);
270 PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
271 instance->uni_bi_reg - instance->reg_base, tmp);
272
273 tmp = inw(instance->current_on_reg); // Volts only!
274 tmp &= ~(0x1 << instance->ao_idx);
275 tmp &= 0x00FF;
276 outw(tmp, instance->current_on_reg);
277 PDEBUG_REG("current_on_reg outl(0x%lX+0x%lX)=0x%x\n",
278 instance->reg_base,
279 instance->current_on_reg - instance->reg_base, tmp);
280
281 tmp = inw(instance->i_range_reg); // 0..20mA <= If exists.
282 tmp &= ~(0x1 << instance->ao_idx);
283 outw(tmp, instance->i_range_reg);
284 PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
285 instance->i_range_reg - instance->reg_base, tmp);
286
287 outw(0, (instance->ao_regs_shadows)->registry[instance->ao_idx]);
288 PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
289 (instance->ao_regs_shadows)->registry[instance->ao_idx] -
290 instance->reg_base, 0);
291
292 // Trigger output.
293 outw(0x0000, instance->sim_output_reg);
294 PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
295 instance->reg_base,
296 instance->sim_output_reg - instance->reg_base, 0x0000);
297 outw(0xFFFF, instance->sim_output_reg);
298 PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
299 instance->reg_base,
300 instance->sim_output_reg - instance->reg_base, 0xFFFF);
301 spin_unlock(instance->config_regs_lock);
302 spin_unlock(instance->ao_shadows_lock);
303
304 // Set status to 'none'
305 instance->status = ao_status_none;
306 spin_unlock(&instance->subdevice_lock);
307
308 //Signal reset if user is on wait.
309 wake_up_interruptible_all(&instance->wait_queue);
310
311 ME_SUBDEVICE_EXIT;
312
313 return ME_ERRNO_SUCCESS;
314}
315
316static int me1600_ao_io_single_config(me_subdevice_t * subdevice,
317 struct file *filep,
318 int channel,
319 int single_config,
320 int ref,
321 int trig_chan,
322 int trig_type, int trig_edge, int flags)
323{
324 me1600_ao_subdevice_t *instance;
325 uint16_t tmp;
326
327 instance = (me1600_ao_subdevice_t *) subdevice;
328
329 PDEBUG("executed. idx=%d\n", instance->ao_idx);
330
331 // Checking parameters.
332 if (flags) {
333 PERROR
334 ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n");
335 return ME_ERRNO_INVALID_FLAGS;
336 }
337
338 if (trig_edge != ME_TRIG_EDGE_NONE) {
339 PERROR
340 ("Invalid trigger edge. Software trigger has not edge. Must be ME_TRIG_EDGE_NONE\n");
341 return ME_ERRNO_INVALID_TRIG_EDGE;
342 }
343
344 if (trig_type != ME_TRIG_TYPE_SW) {
345 PERROR("Invalid trigger edge. Must be ME_TRIG_TYPE_SW.\n");
346 return ME_ERRNO_INVALID_TRIG_TYPE;
347 }
348
349 if ((trig_chan != ME_TRIG_CHAN_DEFAULT)
350 && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) {
351 PERROR("Invalid trigger channel specified.\n");
352 return ME_ERRNO_INVALID_TRIG_CHAN;
353 }
354
355 if (ref != ME_REF_AO_GROUND) {
356 PERROR
357 ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n");
358 return ME_ERRNO_INVALID_REF;
359 }
360
361 if (((single_config + 1) >
362 (instance->u_ranges_count + instance->i_ranges_count))
363 || (single_config < 0)) {
364 PERROR("Invalid range specified.\n");
365 return ME_ERRNO_INVALID_SINGLE_CONFIG;
366 }
367
368 if (channel) {
369 PERROR("Invalid channel specified.\n");
370 return ME_ERRNO_INVALID_CHANNEL;
371 }
372 // Checking parameters - done. All is fine. Do config.
373
374 ME_SUBDEVICE_ENTER;
375
376 //Cancel control task
377 PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
378 instance->ao_control_task_flag = 0;
379 cancel_delayed_work(&instance->ao_control_task);
380
381 spin_lock(&instance->subdevice_lock);
382 spin_lock(instance->ao_shadows_lock);
383 (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Cancell waiting for trigger.
384 (instance->ao_regs_shadows)->shadow[instance->ao_idx] = 0;
385 (instance->ao_regs_shadows)->mirror[instance->ao_idx] = 0;
386
387 spin_lock(instance->config_regs_lock);
388 switch (single_config) {
389 case 0: // 0V 10V
390 tmp = inw(instance->current_on_reg); // Volts
391 tmp &= ~(0x1 << instance->ao_idx);
392 outw(tmp, instance->current_on_reg);
393 PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
394 instance->reg_base,
395 instance->current_on_reg - instance->reg_base, tmp);
396
397 // 0V
398 outw(0,
399 (instance->ao_regs_shadows)->registry[instance->ao_idx]);
400 PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
401 instance->reg_base,
402 (instance->ao_regs_shadows)->registry[instance->
403 ao_idx] -
404 instance->reg_base, 0);
405
406 tmp = inw(instance->uni_bi_reg); // unipolar
407 tmp |= (0x1 << instance->ao_idx);
408 outw(tmp, instance->uni_bi_reg);
409 PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
410 instance->reg_base,
411 instance->uni_bi_reg - instance->reg_base, tmp);
412
413 tmp = inw(instance->i_range_reg); // 0..20mA <= If exists.
414 tmp &= ~(0x1 << instance->ao_idx);
415 outw(tmp, instance->i_range_reg);
416 PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
417 instance->reg_base,
418 instance->i_range_reg - instance->reg_base, tmp);
419 break;
420
421 case 1: // -10V 10V
422 tmp = inw(instance->current_on_reg); // Volts
423 tmp &= ~(0x1 << instance->ao_idx);
424 outw(tmp, instance->current_on_reg);
425 PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
426 instance->reg_base,
427 instance->current_on_reg - instance->reg_base, tmp);
428
429 // 0V
430 outw(0x0800,
431 (instance->ao_regs_shadows)->registry[instance->ao_idx]);
432 PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
433 instance->reg_base,
434 (instance->ao_regs_shadows)->registry[instance->
435 ao_idx] -
436 instance->reg_base, 0x0800);
437
438 tmp = inw(instance->uni_bi_reg); // bipolar
439 tmp &= ~(0x1 << instance->ao_idx);
440 outw(tmp, instance->uni_bi_reg);
441 PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
442 instance->reg_base,
443 instance->uni_bi_reg - instance->reg_base, tmp);
444
445 tmp = inw(instance->i_range_reg); // 0..20mA <= If exists.
446 tmp &= ~(0x1 << instance->ao_idx);
447 outw(tmp, instance->i_range_reg);
448 PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
449 instance->reg_base,
450 instance->i_range_reg - instance->reg_base, tmp);
451 break;
452
453 case 2: // 0mA 20mA
454 tmp = inw(instance->current_on_reg); // mAmpers
455 tmp |= (0x1 << instance->ao_idx);
456 outw(tmp, instance->current_on_reg);
457 PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
458 instance->reg_base,
459 instance->current_on_reg - instance->reg_base, tmp);
460
461 tmp = inw(instance->i_range_reg); // 0..20mA
462 tmp &= ~(0x1 << instance->ao_idx);
463 outw(tmp, instance->i_range_reg);
464 PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
465 instance->reg_base,
466 instance->i_range_reg - instance->reg_base, tmp);
467
468 // 0mA
469 outw(0,
470 (instance->ao_regs_shadows)->registry[instance->ao_idx]);
471 PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
472 instance->reg_base,
473 (instance->ao_regs_shadows)->registry[instance->
474 ao_idx] -
475 instance->reg_base, 0);
476
477 tmp = inw(instance->uni_bi_reg); // unipolar
478 tmp |= (0x1 << instance->ao_idx);
479 outw(tmp, instance->uni_bi_reg);
480 PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
481 instance->reg_base,
482 instance->uni_bi_reg - instance->reg_base, tmp);
483 break;
484
485 case 3: // 4mA 20mA
486 tmp = inw(instance->current_on_reg); // mAmpers
487 tmp |= (0x1 << instance->ao_idx);
488 outw(tmp, instance->current_on_reg);
489 PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
490 instance->reg_base,
491 instance->current_on_reg - instance->reg_base, tmp);
492
493 tmp = inw(instance->i_range_reg); // 4..20mA
494 tmp |= (0x1 << instance->ao_idx);
495 outw(tmp, instance->i_range_reg);
496 PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
497 instance->reg_base,
498 instance->i_range_reg - instance->reg_base, tmp);
499
500 // 4mA
501 outw(0,
502 (instance->ao_regs_shadows)->registry[instance->ao_idx]);
503 PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
504 instance->reg_base,
505 (instance->ao_regs_shadows)->registry[instance->
506 ao_idx] -
507 instance->reg_base, 0);
508
509 tmp = inw(instance->uni_bi_reg); // unipolar
510 tmp |= (0x1 << instance->ao_idx);
511 outw(tmp, instance->uni_bi_reg);
512 PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
513 instance->reg_base,
514 instance->uni_bi_reg - instance->reg_base, tmp);
515 break;
516 }
517
518 // Trigger output.
519 outw(0x0000, instance->sim_output_reg);
520 PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
521 instance->reg_base,
522 instance->sim_output_reg - instance->reg_base, 0x0000);
523 outw(0xFFFF, instance->sim_output_reg);
524 PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
525 instance->reg_base,
526 instance->sim_output_reg - instance->reg_base, 0xFFFF);
527
528 if (trig_chan == ME_TRIG_CHAN_DEFAULT) { // Individual triggering.
529 (instance->ao_regs_shadows)->synchronous &=
530 ~(0x1 << instance->ao_idx);
531 PDEBUG("Individual triggering.\n");
532 } else if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS) { // Synchronous triggering.
533 (instance->ao_regs_shadows)->synchronous |=
534 (0x1 << instance->ao_idx);
535 PDEBUG("Synchronous triggering.\n");
536 }
537 spin_unlock(instance->config_regs_lock);
538 spin_unlock(instance->ao_shadows_lock);
539
540 instance->status = ao_status_single_configured;
541 spin_unlock(&instance->subdevice_lock);
542
543 ME_SUBDEVICE_EXIT;
544
545 return ME_ERRNO_SUCCESS;
546}
547
548static int me1600_ao_io_single_read(me_subdevice_t * subdevice,
549 struct file *filep,
550 int channel,
551 int *value, int time_out, int flags)
552{
553 me1600_ao_subdevice_t *instance;
554 unsigned long delay = 0;
555 unsigned long j = 0;
556 int err = ME_ERRNO_SUCCESS;
557
558 instance = (me1600_ao_subdevice_t *) subdevice;
559
560 PDEBUG("executed. idx=%d\n", instance->ao_idx);
561
562 if (flags & ~ME_IO_SINGLE_NONBLOCKING) {
563 PERROR("Invalid flag specified. %d\n", flags);
564 return ME_ERRNO_INVALID_FLAGS;
565 }
566
567 if (time_out < 0) {
568 PERROR("Invalid timeout specified.\n");
569 return ME_ERRNO_INVALID_TIMEOUT;
570 }
571
572 if (channel) {
573 PERROR("Invalid channel specified.\n");
574 return ME_ERRNO_INVALID_CHANNEL;
575 }
576
577 if ((!flags) && ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) { //Blocking mode. Wait for software trigger.
578 if (time_out) {
579 delay = (time_out * HZ) / 1000;
580 if (delay == 0)
581 delay = 1;
582 }
583
584 j = jiffies;
585
586 //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
587 wait_event_interruptible_timeout(instance->wait_queue,
588 (!((instance->
589 ao_regs_shadows)->
590 trigger & instance->
591 ao_idx)),
592 (delay) ? delay : LONG_MAX);
593
594 if (instance == ao_status_none) { // Reset was called.
595 PDEBUG("Single canceled.\n");
596 err = ME_ERRNO_CANCELLED;
597 }
598
599 if (signal_pending(current)) {
600 PERROR("Wait on start of state machine interrupted.\n");
601 err = ME_ERRNO_SIGNAL;
602 }
603
604 if ((delay) && ((jiffies - j) >= delay)) {
605 PDEBUG("Timeout reached.\n");
606 err = ME_ERRNO_TIMEOUT;
607 }
608 }
609
610 *value = (instance->ao_regs_shadows)->mirror[instance->ao_idx];
611
612 return err;
613}
614
615static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
616 struct file *filep,
617 int channel,
618 int value, int time_out, int flags)
619{
620 me1600_ao_subdevice_t *instance;
621 int err = ME_ERRNO_SUCCESS;
622 unsigned long delay = 0;
623 int i;
624 unsigned long j = 0;
625
626 instance = (me1600_ao_subdevice_t *) subdevice;
627
628 PDEBUG("executed. idx=%d\n", instance->ao_idx);
629
630 if (flags &
631 ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS |
632 ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
633 PERROR("Invalid flag specified.\n");
634 return ME_ERRNO_INVALID_FLAGS;
635 }
636
637 if (time_out < 0) {
638 PERROR("Invalid timeout specified.\n");
639 return ME_ERRNO_INVALID_TIMEOUT;
640 }
641
642 if (value & ~ME1600_AO_MAX_DATA) {
643 PERROR("Invalid value provided.\n");
644 return ME_ERRNO_VALUE_OUT_OF_RANGE;
645 }
646
647 if (channel) {
648 PERROR("Invalid channel specified.\n");
649 return ME_ERRNO_INVALID_CHANNEL;
650 }
651
652 ME_SUBDEVICE_ENTER;
653
654 //Cancel control task
655 PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
656 instance->ao_control_task_flag = 0;
657 cancel_delayed_work(&instance->ao_control_task);
658 (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Cancell waiting for trigger.
659
660 if (time_out) {
661 delay = (time_out * HZ) / 1000;
662
663 if (delay == 0)
664 delay = 1;
665 }
666 //Write value.
667 spin_lock(instance->ao_shadows_lock);
668 (instance->ao_regs_shadows)->shadow[instance->ao_idx] =
669 (uint16_t) value;
670
671 if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { // Trigger all outputs from synchronous list.
672 for (i = 0; i < (instance->ao_regs_shadows)->count; i++) {
673 if (((instance->ao_regs_shadows)->synchronous & (0x1 << i)) || (i == instance->ao_idx)) { // Set all from synchronous list to correct state.
674 PDEBUG
675 ("Synchronous triggering: output %d. idx=%d\n",
676 i, instance->ao_idx);
677 (instance->ao_regs_shadows)->mirror[i] =
678 (instance->ao_regs_shadows)->shadow[i];
679
680 outw((instance->ao_regs_shadows)->shadow[i],
681 (instance->ao_regs_shadows)->registry[i]);
682 PDEBUG_REG
683 ("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
684 instance->reg_base,
685 (instance->ao_regs_shadows)->registry[i] -
686 instance->reg_base,
687 (instance->ao_regs_shadows)->shadow[i]);
688
689 (instance->ao_regs_shadows)->trigger &=
690 ~(0x1 << i);
691 }
692 }
693
694 // Trigger output.
695 outw(0x0000, instance->sim_output_reg);
696 PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
697 instance->reg_base,
698 instance->sim_output_reg - instance->reg_base, 0);
699 outw(0xFFFF, instance->sim_output_reg);
700 PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
701 instance->reg_base,
702 instance->sim_output_reg - instance->reg_base,
703 0xFFFF);
704 instance->status = ao_status_single_end;
705 } else { // Individual mode.
706 if ((instance->ao_regs_shadows)->synchronous & (0x1 << instance->ao_idx)) { // Put on synchronous start list. Set output as waiting for trigger.
707 PDEBUG("Add to synchronous list. idx=%d\n",
708 instance->ao_idx);
709 (instance->ao_regs_shadows)->trigger |=
710 (0x1 << instance->ao_idx);
711 instance->status = ao_status_single_run;
712 PDEBUG("Synchronous list: 0x%x.\n",
713 (instance->ao_regs_shadows)->synchronous);
714 } else { // Fired this one.
715 PDEBUG("Triggering. idx=%d\n", instance->ao_idx);
716 (instance->ao_regs_shadows)->mirror[instance->ao_idx] =
717 (instance->ao_regs_shadows)->shadow[instance->
718 ao_idx];
719
720 outw((instance->ao_regs_shadows)->
721 shadow[instance->ao_idx],
722 (instance->ao_regs_shadows)->registry[instance->
723 ao_idx]);
724 PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
725 instance->reg_base,
726 (instance->ao_regs_shadows)->
727 registry[instance->ao_idx] -
728 instance->reg_base,
729 (instance->ao_regs_shadows)->
730 shadow[instance->ao_idx]);
731
732 // Set output as triggered.
733 (instance->ao_regs_shadows)->trigger &=
734 ~(0x1 << instance->ao_idx);
735
736 // Trigger output.
737 outw(0x0000, instance->sim_output_reg);
738 PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
739 instance->reg_base,
740 instance->sim_output_reg -
741 instance->reg_base, 0);
742 outw(0xFFFF, instance->sim_output_reg);
743 PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
744 instance->reg_base,
745 instance->sim_output_reg -
746 instance->reg_base, 0xFFFF);
747 instance->status = ao_status_single_end;
748 }
749 }
750 spin_unlock(instance->ao_shadows_lock);
751
752 //Init control task
753 instance->timeout.delay = delay;
754 instance->timeout.start_time = jiffies;
755 instance->ao_control_task_flag = 1;
756 queue_delayed_work(instance->me1600_workqueue,
757 &instance->ao_control_task, 1);
758
759 if ((!flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING) && ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) { //Blocking mode. Wait for software trigger.
760 if (time_out) {
761 delay = (time_out * HZ) / 1000;
762 if (delay == 0)
763 delay = 1;
764 }
765
766 j = jiffies;
767
768 //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
769 wait_event_interruptible_timeout(instance->wait_queue,
770 (!((instance->
771 ao_regs_shadows)->
772 trigger & instance->
773 ao_idx)),
774 (delay) ? delay : LONG_MAX);
775
776 if (instance == ao_status_none) {
777 PDEBUG("Single canceled.\n");
778 err = ME_ERRNO_CANCELLED;
779 }
780 if (signal_pending(current)) {
781 PERROR("Wait on start of state machine interrupted.\n");
782 err = ME_ERRNO_SIGNAL;
783 }
784
785 if ((delay) && ((jiffies - j) >= delay)) {
786 PDEBUG("Timeout reached.\n");
787 err = ME_ERRNO_TIMEOUT;
788 }
789 }
790
791 ME_SUBDEVICE_EXIT;
792
793 return err;
794}
795
796static int me1600_ao_query_number_channels(me_subdevice_t * subdevice,
797 int *number)
798{
799 me1600_ao_subdevice_t *instance;
800 instance = (me1600_ao_subdevice_t *) subdevice;
801
802 PDEBUG("executed. idx=%d\n", instance->ao_idx);
803
804 *number = 1; //Every subdevice has only 1 channel.
805 return ME_ERRNO_SUCCESS;
806}
807
808static int me1600_ao_query_subdevice_type(me_subdevice_t * subdevice, int *type,
809 int *subtype)
810{
811 me1600_ao_subdevice_t *instance;
812 instance = (me1600_ao_subdevice_t *) subdevice;
813
814 PDEBUG("executed. idx=%d\n", instance->ao_idx);
815
816 *type = ME_TYPE_AO;
817 *subtype = ME_SUBTYPE_SINGLE;
818 return ME_ERRNO_SUCCESS;
819}
820
821static int me1600_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
822{
823 PDEBUG("executed.\n");
824 *caps = ME_CAPS_AO_TRIG_SYNCHRONOUS;
825 return ME_ERRNO_SUCCESS;
826}
827
828static int me1600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
829 int unit,
830 int *min,
831 int *max, int *maxdata, int *range)
832{
833 me1600_ao_subdevice_t *instance;
834 int i;
835 int r = -1;
836 int diff = 21E6;
837
838 instance = (me1600_ao_subdevice_t *) subdevice;
839
840 PDEBUG("executed. idx=%d\n", instance->ao_idx);
841
842 if ((*max - *min) < 0) {
843 PERROR("Invalid minimum and maximum values specified.\n");
844 return ME_ERRNO_INVALID_MIN_MAX;
845 }
846 // Maximum ranges are slightly less then 10V or 20mA. For convenient we accepted this value as valid one.
847 if (unit == ME_UNIT_VOLT) {
848 for (i = 0; i < instance->u_ranges_count; i++) {
849 if ((instance->u_ranges[i].min <= *min)
850 && ((instance->u_ranges[i].max + 5000) >= *max)) {
851 if ((instance->u_ranges[i].max -
852 instance->u_ranges[i].min) - (*max -
853 *min) <
854 diff) {
855 r = i;
856 diff =
857 (instance->u_ranges[i].max -
858 instance->u_ranges[i].min) -
859 (*max - *min);
860 }
861 }
862 }
863
864 if (r < 0) {
865 PERROR("No matching range found.\n");
866 return ME_ERRNO_NO_RANGE;
867 } else {
868 *min = instance->u_ranges[r].min;
869 *max = instance->u_ranges[r].max;
870 *range = r;
871 }
872 } else if (unit == ME_UNIT_AMPERE) {
873 for (i = 0; i < instance->i_ranges_count; i++) {
874 if ((instance->i_ranges[i].min <= *min)
875 && (instance->i_ranges[i].max + 5000 >= *max)) {
876 if ((instance->i_ranges[i].max -
877 instance->i_ranges[i].min) - (*max -
878 *min) <
879 diff) {
880 r = i;
881 diff =
882 (instance->i_ranges[i].max -
883 instance->i_ranges[i].min) -
884 (*max - *min);
885 }
886 }
887 }
888
889 if (r < 0) {
890 PERROR("No matching range found.\n");
891 return ME_ERRNO_NO_RANGE;
892 } else {
893 *min = instance->i_ranges[r].min;
894 *max = instance->i_ranges[r].max;
895 *range = r + instance->u_ranges_count;
896 }
897 } else {
898 PERROR("Invalid physical unit specified.\n");
899 return ME_ERRNO_INVALID_UNIT;
900 }
901 *maxdata = ME1600_AO_MAX_DATA;
902
903 return ME_ERRNO_SUCCESS;
904}
905
906static int me1600_ao_query_number_ranges(me_subdevice_t * subdevice,
907 int unit, int *count)
908{
909 me1600_ao_subdevice_t *instance;
910
911 PDEBUG("executed.\n");
912
913 instance = (me1600_ao_subdevice_t *) subdevice;
914 switch (unit) {
915 case ME_UNIT_VOLT:
916 *count = instance->u_ranges_count;
917 break;
918 case ME_UNIT_AMPERE:
919 *count = instance->i_ranges_count;
920 break;
921 case ME_UNIT_ANY:
922 *count = instance->u_ranges_count + instance->i_ranges_count;
923 break;
924 default:
925 *count = 0;
926 }
927
928 return ME_ERRNO_SUCCESS;
929}
930
931static int me1600_ao_query_range_info(me_subdevice_t * subdevice,
932 int range,
933 int *unit,
934 int *min, int *max, int *maxdata)
935{
936 me1600_ao_subdevice_t *instance;
937
938 PDEBUG("executed.\n");
939
940 instance = (me1600_ao_subdevice_t *) subdevice;
941
942 if (((range + 1) >
943 (instance->u_ranges_count + instance->i_ranges_count))
944 || (range < 0)) {
945 PERROR("Invalid range number specified.\n");
946 return ME_ERRNO_INVALID_RANGE;
947 }
948
949 if (range < instance->u_ranges_count) {
950 *unit = ME_UNIT_VOLT;
951 *min = instance->u_ranges[range].min;
952 *max = instance->u_ranges[range].max;
953 } else if (range < instance->u_ranges_count + instance->i_ranges_count) {
954 *unit = ME_UNIT_AMPERE;
955 *min = instance->i_ranges[range - instance->u_ranges_count].min;
956 *max = instance->i_ranges[range - instance->u_ranges_count].max;
957 }
958 *maxdata = ME1600_AO_MAX_DATA;
959
960 return ME_ERRNO_SUCCESS;
961}
962
963#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
964static void me1600_ao_work_control_task(void *subdevice)
965#else
966static void me1600_ao_work_control_task(struct work_struct *work)
967#endif
968{
969 me1600_ao_subdevice_t *instance;
970 int reschedule = 1;
971 int signaling = 0;
972
973#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
974 instance = (me1600_ao_subdevice_t *) subdevice;
975#else
976 instance =
977 container_of((void *)work, me1600_ao_subdevice_t, ao_control_task);
978#endif
979
980 PINFO("<%s: %ld> executed. idx=%d\n", __FUNCTION__, jiffies,
981 instance->ao_idx);
982
983 if (!((instance->ao_regs_shadows)->trigger & instance->ao_idx)) { // Output was triggerd.
984 // Signal the end.
985 signaling = 1;
986 reschedule = 0;
987 if (instance->status == ao_status_single_run) {
988 instance->status = ao_status_single_end;
989 }
990
991 } else if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
992 PDEBUG("Timeout reached.\n");
993 spin_lock(instance->ao_shadows_lock);
994 // Restore old settings.
995 PDEBUG("Write old value back to register.\n");
996 (instance->ao_regs_shadows)->shadow[instance->ao_idx] =
997 (instance->ao_regs_shadows)->mirror[instance->ao_idx];
998
999 outw((instance->ao_regs_shadows)->mirror[instance->ao_idx],
1000 (instance->ao_regs_shadows)->registry[instance->ao_idx]);
1001 PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
1002 instance->reg_base,
1003 (instance->ao_regs_shadows)->registry[instance->
1004 ao_idx] -
1005 instance->reg_base,
1006 (instance->ao_regs_shadows)->mirror[instance->
1007 ao_idx]);
1008
1009 //Remove from synchronous strt list.
1010 (instance->ao_regs_shadows)->trigger &=
1011 ~(0x1 << instance->ao_idx);
1012 if (instance->status == ao_status_none) {
1013 instance->status = ao_status_single_end;
1014 }
1015 spin_unlock(instance->ao_shadows_lock);
1016
1017 // Signal the end.
1018 signaling = 1;
1019 reschedule = 0;
1020 }
1021
1022 if (signaling) { //Signal it.
1023 wake_up_interruptible_all(&instance->wait_queue);
1024 }
1025
1026 if (instance->ao_control_task_flag && reschedule) { // Reschedule task
1027 queue_delayed_work(instance->me1600_workqueue,
1028 &instance->ao_control_task, 1);
1029 } else {
1030 PINFO("<%s> Ending control task.\n", __FUNCTION__);
1031 }
1032
1033}
diff --git a/drivers/staging/meilhaus/me1600_ao.h b/drivers/staging/meilhaus/me1600_ao.h
new file mode 100644
index 000000000000..b82bf5a1676e
--- /dev/null
+++ b/drivers/staging/meilhaus/me1600_ao.h
@@ -0,0 +1,132 @@
1/**
2 * @file me1600_ao.h
3 *
4 * @brief Meilhaus ME-1600 analog output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME1600_AO_H_
28#define _ME1600_AO_H_
29
30# include <linux/version.h>
31# include "mesubdevice.h"
32
33# ifdef __KERNEL__
34
35# define ME1600_MAX_RANGES 2 /**< Specifies the maximum number of ranges in me1600_ao_subdevice_t::u_ranges und me1600_ao_subdevice_t::i_ranges. */
36
37/**
38 * @brief Defines a entry in the range table.
39 */
40typedef struct me1600_ao_range_entry {
41 int32_t min;
42 int32_t max;
43} me1600_ao_range_entry_t;
44
45typedef struct me1600_ao_timeout {
46 unsigned long start_time;
47 unsigned long delay;
48} me1600_ao_timeout_t;
49
50typedef struct me1600_ao_shadow {
51 int count;
52 unsigned long *registry;
53 uint16_t *shadow;
54 uint16_t *mirror;
55 uint16_t synchronous; /**< Synchronization list. */
56 uint16_t trigger; /**< Synchronization flag. */
57} me1600_ao_shadow_t;
58
59typedef enum ME1600_AO_STATUS {
60 ao_status_none = 0,
61 ao_status_single_configured,
62 ao_status_single_run,
63 ao_status_single_end,
64 ao_status_last
65} ME1600_AO_STATUS;
66
67/**
68 * @brief The ME-1600 analog output subdevice class.
69 */
70typedef struct me1600_ao_subdevice {
71 /* Inheritance */
72 me_subdevice_t base; /**< The subdevice base class. */
73
74 /* Attributes */
75 int ao_idx; /**< The index of the analog output subdevice on the device. */
76
77 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
78 spinlock_t *config_regs_lock; /**< Spin lock to protect configuration registers from concurrent access. */
79
80 int u_ranges_count; /**< The number of voltage ranges available on this subdevice. */
81 me1600_ao_range_entry_t u_ranges[ME1600_MAX_RANGES]; /**< Array holding the voltage ranges on this subdevice. */
82 int i_ranges_count; /**< The number of current ranges available on this subdevice. */
83 me1600_ao_range_entry_t i_ranges[ME1600_MAX_RANGES]; /**< Array holding the current ranges on this subdevice. */
84
85 /* Registers */
86 unsigned long uni_bi_reg; /**< Register for switching between unipoar and bipolar output mode. */
87 unsigned long i_range_reg; /**< Register for switching between ranges. */
88 unsigned long sim_output_reg; /**< Register used in order to update all channels simultaneously. */
89 unsigned long current_on_reg; /**< Register enabling current output on the fourth subdevice. */
90# ifdef PDEBUG_REG
91 unsigned long reg_base;
92# endif
93
94 ME1600_AO_STATUS status;
95 me1600_ao_shadow_t *ao_regs_shadows; /**< Addresses and shadows of output's registers. */
96 spinlock_t *ao_shadows_lock; /**< Protects the shadow's struct. */
97 int mode; /**< Mode in witch output should works. */
98 wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
99 me1600_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
100 struct workqueue_struct *me1600_workqueue;
101#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
102 struct work_struct ao_control_task;
103#else
104 struct delayed_work ao_control_task;
105#endif
106
107 volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
108} me1600_ao_subdevice_t;
109
110/**
111 * @brief The constructor to generate a subdevice template instance.
112 *
113 * @param reg_base The register base address of the device as returned by the PCI BIOS.
114 * @param ao_idx The index of the analog output subdevice on the device.
115 * @param current Flag indicating that analog output with #ao_idx of 3 is capable of current output.
116 * @param config_regs_lock Pointer to spin lock protecting the configuration registers and from concurrent access.
117 *
118 * @return Pointer to new instance on success.\n
119 * NULL on error.
120 */
121me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base,
122 unsigned int ao_idx,
123 int curr,
124 spinlock_t * config_regs_lock,
125 spinlock_t * ao_shadows_lock,
126 me1600_ao_shadow_t *
127 ao_regs_shadows,
128 struct workqueue_struct
129 *me1600_wq);
130
131# endif //__KERNEL__
132#endif //_ME1600_AO_H_
diff --git a/drivers/staging/meilhaus/me1600_ao_reg.h b/drivers/staging/meilhaus/me1600_ao_reg.h
new file mode 100644
index 000000000000..31e7800e8074
--- /dev/null
+++ b/drivers/staging/meilhaus/me1600_ao_reg.h
@@ -0,0 +1,66 @@
1/**
2 * @file me1600_ao_reg.h
3 *
4 * @brief ME-1600 analog output subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME1600_AO_REG_H_
28#define _ME1600_AO_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME1600_CHANNEL_0_REG 0x00 /**< Register to set a digital value on channel 0. */
33#define ME1600_CHANNEL_1_REG 0x02 /**< Register to set a digital value on channel 1. */
34#define ME1600_CHANNEL_2_REG 0x04 /**< Register to set a digital value on channel 2. */
35#define ME1600_CHANNEL_3_REG 0x06 /**< Register to set a digital value on channel 3. */
36#define ME1600_CHANNEL_4_REG 0x08 /**< Register to set a digital value on channel 4. */
37#define ME1600_CHANNEL_5_REG 0x0A /**< Register to set a digital value on channel 5. */
38#define ME1600_CHANNEL_6_REG 0x0C /**< Register to set a digital value on channel 6. */
39#define ME1600_CHANNEL_7_REG 0x0E /**< Register to set a digital value on channel 7. */
40#define ME1600_CHANNEL_8_REG 0x10 /**< Register to set a digital value on channel 8. */
41#define ME1600_CHANNEL_9_REG 0x12 /**< Register to set a digital value on channel 9. */
42#define ME1600_CHANNEL_10_REG 0x14 /**< Register to set a digital value on channel 10. */
43#define ME1600_CHANNEL_11_REG 0x16 /**< Register to set a digital value on channel 11. */
44#define ME1600_CHANNEL_12_REG 0x18 /**< Register to set a digital value on channel 12. */
45#define ME1600_CHANNEL_13_REG 0x1A /**< Register to set a digital value on channel 13. */
46#define ME1600_CHANNEL_14_REG 0x1C /**< Register to set a digital value on channel 14. */
47#define ME1600_CHANNEL_15_REG 0x1E /**< Register to set a digital value on channel 15. */
48
49/* Every channel one bit: bipolar = 0, unipolar = 1 */
50#define ME1600_UNI_BI_REG 0x20 /**< Register to switch between unipolar and bipolar. */
51
52/* Every channel one bit (only lower 8 Bits): 0..20mA = 0, 4..20mA = 1 */
53#define ME1600_020_420_REG 0x22 /**< Register to switch between the two current ranges. */
54
55/* If a bit is set, the corresponding DAC (4 ports each) is
56 not set at the moment you write to an output of it.
57 Clearing the bit updates the port. */
58#define ME1600_SIM_OUTPUT_REG 0x24 /**< Register to update all channels of a subdevice simultaneously. */
59
60/* Current on/off (only lower 8 bits): off = 0, on = 1 */
61#define ME1600_CURRENT_ON_REG 0x26 /**< Register to swicht between voltage and current output. */
62
63#define ME1600_AO_MAX_DATA 0x0FFF /**< The maximum digital data accepted by an analog output channel. */
64
65#endif
66#endif
diff --git a/drivers/staging/meilhaus/me1600_device.c b/drivers/staging/meilhaus/me1600_device.c
new file mode 100644
index 000000000000..3bc2cb1dc869
--- /dev/null
+++ b/drivers/staging/meilhaus/me1600_device.c
@@ -0,0 +1,261 @@
1/**
2 * @file me1600_device.c
3 *
4 * @brief ME-1600 device class implementation.
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#ifndef MODULE
33# define MODULE
34#endif
35
36#include <linux/module.h>
37
38#include <linux/pci.h>
39#include <linux/slab.h>
40
41#include "meids.h"
42#include "meerror.h"
43#include "mecommon.h"
44#include "meinternal.h"
45
46#include "medebug.h"
47#include "medevice.h"
48#include "mesubdevice.h"
49#include "me1600_device.h"
50
51static void me1600_set_registry(me1600_device_t * subdevice, uint32_t reg_base);
52static void me1600_destructor(struct me_device *device);
53
54/**
55 * @brief Global variable.
56 * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts).
57 */
58static struct workqueue_struct *me1600_workqueue;
59
60me_device_t *me1600_pci_constructor(struct pci_dev *pci_device)
61{
62 int err;
63 me1600_device_t *me1600_device;
64 me_subdevice_t *subdevice;
65 unsigned int chip_idx;
66 int i;
67
68 PDEBUG("executed.\n");
69
70 // Allocate structure for device instance.
71 me1600_device = kmalloc(sizeof(me1600_device_t), GFP_KERNEL);
72
73 if (!me1600_device) {
74 PERROR("Cannot get memory for device instance.\n");
75 return NULL;
76 }
77
78 memset(me1600_device, 0, sizeof(me1600_device_t));
79
80 // Initialize base class structure.
81 err = me_device_pci_init((me_device_t *) me1600_device, pci_device);
82
83 if (err) {
84 kfree(me1600_device);
85 PERROR("Cannot initialize device base class.\n");
86 return NULL;
87 }
88 // Initialize spin lock .
89 spin_lock_init(&me1600_device->config_regs_lock);
90 spin_lock_init(&me1600_device->ao_shadows_lock);
91
92 // Get the number of analog output subdevices.
93 chip_idx =
94 me1600_versions_get_device_index(me1600_device->base.info.pci.
95 device_id);
96
97 // Create shadow instance.
98 me1600_device->ao_regs_shadows.count =
99 me1600_versions[chip_idx].ao_chips;
100 me1600_device->ao_regs_shadows.registry =
101 kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(unsigned long),
102 GFP_KERNEL);
103 me1600_set_registry(me1600_device,
104 me1600_device->base.info.pci.reg_bases[2]);
105 me1600_device->ao_regs_shadows.shadow =
106 kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(uint16_t),
107 GFP_KERNEL);
108 me1600_device->ao_regs_shadows.mirror =
109 kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(uint16_t),
110 GFP_KERNEL);
111
112 // Create subdevice instances.
113 for (i = 0; i < me1600_versions[chip_idx].ao_chips; i++) {
114 subdevice =
115 (me_subdevice_t *) me1600_ao_constructor(me1600_device->
116 base.info.pci.
117 reg_bases[2], i,
118 ((me1600_versions
119 [chip_idx].curr >
120 i) ? 1 : 0),
121 &me1600_device->
122 config_regs_lock,
123 &me1600_device->
124 ao_shadows_lock,
125 &me1600_device->
126 ao_regs_shadows,
127 me1600_workqueue);
128
129 if (!subdevice) {
130 me_device_deinit((me_device_t *) me1600_device);
131 kfree(me1600_device);
132 PERROR("Cannot get memory for subdevice.\n");
133 return NULL;
134 }
135
136 me_slist_add_subdevice_tail(&me1600_device->base.slist,
137 subdevice);
138 }
139
140 // Overwrite base class methods.
141 me1600_device->base.me_device_destructor = me1600_destructor;
142
143 return (me_device_t *) me1600_device;
144}
145
146static void me1600_destructor(struct me_device *device)
147{
148 me1600_device_t *me1600_device = (me1600_device_t *) device;
149 PDEBUG("executed.\n");
150
151 // Destroy shadow instance.
152 kfree(me1600_device->ao_regs_shadows.registry);
153 kfree(me1600_device->ao_regs_shadows.shadow);
154 kfree(me1600_device->ao_regs_shadows.mirror);
155
156 me_device_deinit((me_device_t *) me1600_device);
157 kfree(me1600_device);
158}
159
160static void me1600_set_registry(me1600_device_t * subdevice, uint32_t reg_base)
161{ // Create shadow structure.
162 if (subdevice->ao_regs_shadows.count >= 1) {
163 subdevice->ao_regs_shadows.registry[0] =
164 (unsigned long)(reg_base + ME1600_CHANNEL_0_REG);
165 }
166 if (subdevice->ao_regs_shadows.count >= 2) {
167 subdevice->ao_regs_shadows.registry[1] =
168 (unsigned long)(reg_base + ME1600_CHANNEL_1_REG);
169 }
170 if (subdevice->ao_regs_shadows.count >= 3) {
171 subdevice->ao_regs_shadows.registry[2] =
172 (unsigned long)(reg_base + ME1600_CHANNEL_2_REG);
173 }
174 if (subdevice->ao_regs_shadows.count >= 4) {
175 subdevice->ao_regs_shadows.registry[3] =
176 (unsigned long)(reg_base + ME1600_CHANNEL_3_REG);
177 }
178 if (subdevice->ao_regs_shadows.count >= 5) {
179 subdevice->ao_regs_shadows.registry[4] =
180 (unsigned long)(reg_base + ME1600_CHANNEL_4_REG);
181 }
182 if (subdevice->ao_regs_shadows.count >= 6) {
183 subdevice->ao_regs_shadows.registry[5] =
184 (unsigned long)(reg_base + ME1600_CHANNEL_5_REG);
185 }
186 if (subdevice->ao_regs_shadows.count >= 7) {
187 subdevice->ao_regs_shadows.registry[6] =
188 (unsigned long)(reg_base + ME1600_CHANNEL_6_REG);
189 }
190 if (subdevice->ao_regs_shadows.count >= 8) {
191 subdevice->ao_regs_shadows.registry[7] =
192 (unsigned long)(reg_base + ME1600_CHANNEL_7_REG);
193 }
194 if (subdevice->ao_regs_shadows.count >= 9) {
195 subdevice->ao_regs_shadows.registry[8] =
196 (unsigned long)(reg_base + ME1600_CHANNEL_8_REG);
197 }
198 if (subdevice->ao_regs_shadows.count >= 10) {
199 subdevice->ao_regs_shadows.registry[9] =
200 (unsigned long)(reg_base + ME1600_CHANNEL_9_REG);
201 }
202 if (subdevice->ao_regs_shadows.count >= 11) {
203 subdevice->ao_regs_shadows.registry[10] =
204 (unsigned long)(reg_base + ME1600_CHANNEL_10_REG);
205 }
206 if (subdevice->ao_regs_shadows.count >= 12) {
207 subdevice->ao_regs_shadows.registry[11] =
208 (unsigned long)(reg_base + ME1600_CHANNEL_11_REG);
209 }
210 if (subdevice->ao_regs_shadows.count >= 13) {
211 subdevice->ao_regs_shadows.registry[12] =
212 (unsigned long)(reg_base + ME1600_CHANNEL_12_REG);
213 }
214 if (subdevice->ao_regs_shadows.count >= 14) {
215 subdevice->ao_regs_shadows.registry[13] =
216 (unsigned long)(reg_base + ME1600_CHANNEL_13_REG);
217 }
218 if (subdevice->ao_regs_shadows.count >= 15) {
219 subdevice->ao_regs_shadows.registry[14] =
220 (unsigned long)(reg_base + ME1600_CHANNEL_14_REG);
221 }
222 if (subdevice->ao_regs_shadows.count >= 16) {
223 subdevice->ao_regs_shadows.registry[15] =
224 (unsigned long)(reg_base + ME1600_CHANNEL_15_REG);
225 }
226 if (subdevice->ao_regs_shadows.count > 16) {
227 PERROR("More than 16 outputs! (%d)\n",
228 subdevice->ao_regs_shadows.count);
229 }
230}
231
232// Init and exit of module.
233
234static int __init me1600_init(void)
235{
236 PDEBUG("executed\n.");
237
238 me1600_workqueue = create_singlethread_workqueue("me1600");
239 return 0;
240}
241
242static void __exit me1600_exit(void)
243{
244 PDEBUG("executed\n.");
245
246 flush_workqueue(me1600_workqueue);
247 destroy_workqueue(me1600_workqueue);
248}
249
250module_init(me1600_init);
251module_exit(me1600_exit);
252
253// Administrative stuff for modinfo.
254MODULE_AUTHOR
255 ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
256MODULE_DESCRIPTION("Device Driver Module for ME-1600 Device");
257MODULE_SUPPORTED_DEVICE("Meilhaus ME-1600 Devices");
258MODULE_LICENSE("GPL");
259
260// Export the constructor.
261EXPORT_SYMBOL(me1600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me1600_device.h b/drivers/staging/meilhaus/me1600_device.h
new file mode 100644
index 000000000000..f7b231f73ac8
--- /dev/null
+++ b/drivers/staging/meilhaus/me1600_device.h
@@ -0,0 +1,101 @@
1/**
2 * @file me1600_device.h
3 *
4 * @brief ME-1600 device class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME1600_H
28#define _ME1600_H
29
30#include <linux/pci.h>
31#include <linux/spinlock.h>
32
33#include "medevice.h"
34#include "me1600_ao.h"
35#include "me1600_ao_reg.h"
36
37#ifdef __KERNEL__
38
39/**
40 * @brief Structure to store device capabilities.
41 */
42typedef struct me1600_version {
43 uint16_t device_id; /**< The PCI device id of the device. */
44 unsigned int ao_chips; /**< The number of analog outputs on the device. */
45 int curr; /**< Flag to identify amounts of current output. */
46} me1600_version_t;
47
48/**
49 * @brief Defines for each ME-1600 device version its capabilities.
50 */
51static me1600_version_t me1600_versions[] = {
52 {PCI_DEVICE_ID_MEILHAUS_ME1600_4U, 4, 0},
53 {PCI_DEVICE_ID_MEILHAUS_ME1600_8U, 8, 0},
54 {PCI_DEVICE_ID_MEILHAUS_ME1600_12U, 12, 0},
55 {PCI_DEVICE_ID_MEILHAUS_ME1600_16U, 16, 0},
56 {PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I, 16, 8},
57 {0}
58};
59
60/**< Returns the number of entries in #me1600_versions. */
61#define ME1600_DEVICE_VERSIONS (sizeof(me1600_versions) / sizeof(me1600_version_t) - 1)
62
63/**
64 * @brief Returns the index of the device entry in #me1600_versions.
65 *
66 * @param device_id The PCI device id of the device to query.
67 * @return The index of the device in #me1600_versions.
68 */
69static inline unsigned int me1600_versions_get_device_index(uint16_t device_id)
70{
71 unsigned int i;
72 for (i = 0; i < ME1600_DEVICE_VERSIONS; i++)
73 if (me1600_versions[i].device_id == device_id)
74 break;
75 return i;
76}
77
78/**
79 * @brief The ME-1600 device class structure.
80 */
81typedef struct me1600_device {
82 me_device_t base; /**< The Meilhaus device base class. */
83 spinlock_t config_regs_lock; /**< Protects the configuration registers. */
84
85 me1600_ao_shadow_t ao_regs_shadows; /**< Addresses and shadows of output's registers. */
86 spinlock_t ao_shadows_lock; /**< Protects the shadow's struct. */
87} me1600_device_t;
88
89/**
90 * @brief The ME-1600 device class constructor.
91 *
92 * @param pci_device The pci device structure given by the PCI subsystem.
93 *
94 * @return On succes a new ME-1600 device instance. \n
95 * NULL on error.
96 */
97me_device_t *me1600_pci_constructor(struct pci_dev *pci_device)
98 __attribute__ ((weak));
99
100#endif
101#endif
diff --git a/drivers/staging/meilhaus/me4600_ai.c b/drivers/staging/meilhaus/me4600_ai.c
new file mode 100644
index 000000000000..1a0de5dea277
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_ai.c
@@ -0,0 +1,3434 @@
1/**
2 * @file me4600_ai.c
3 *
4 * @brief ME-4000 analog 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 <asm/uaccess.h>
41#include <linux/types.h>
42#include <linux/interrupt.h>
43#include <linux/delay.h>
44
45#include "medefines.h"
46#include "meinternal.h"
47#include "meerror.h"
48#include "medebug.h"
49#include "meids.h"
50
51#include "me4600_reg.h"
52#include "me4600_ai_reg.h"
53#include "me4600_ai.h"
54
55/*
56 * Declarations (local)
57 */
58
59static void me4600_ai_destructor(struct me_subdevice *subdevice);
60static int me4600_ai_io_reset_subdevice(me_subdevice_t * subdevice,
61 struct file *filep, int flags);
62
63static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
64 struct file *filep,
65 int channel,
66 int single_config,
67 int ref,
68 int trig_chan,
69 int trig_type, int trig_edge, int flags);
70
71static int me4600_ai_io_single_read(me_subdevice_t * subdevice,
72 struct file *filep,
73 int channel,
74 int *value, int time_out, int flags);
75
76static int me4600_ai_io_stream_config(me_subdevice_t * subdevice,
77 struct file *filep,
78 meIOStreamConfig_t * config_list,
79 int count,
80 meIOStreamTrigger_t * trigger,
81 int fifo_irq_threshold, int flags);
82static int me4600_ai_io_stream_read(me_subdevice_t * subdevice,
83 struct file *filep,
84 int read_mode,
85 int *values, int *count, int flags);
86static int me4600_ai_io_stream_new_values(me_subdevice_t * subdevice,
87 struct file *filep,
88 int time_out, int *count, int flags);
89static int inline me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
90 instance, int *values,
91 const int count,
92 const int flags);
93
94static int me4600_ai_io_stream_start(me_subdevice_t * subdevice,
95 struct file *filep,
96 int start_mode, int time_out, int flags);
97static int me4600_ai_io_stream_stop(me_subdevice_t * subdevice,
98 struct file *filep,
99 int stop_mode, int flags);
100static int me4600_ai_io_stream_status(me_subdevice_t * subdevice,
101 struct file *filep,
102 int wait,
103 int *status, int *values, int flags);
104
105static int me4600_ai_query_range_by_min_max(me_subdevice_t * subdevice,
106 int unit,
107 int *min,
108 int *max, int *maxdata, int *range);
109static int me4600_ai_query_number_ranges(me_subdevice_t * subdevice,
110 int unit, int *count);
111static int me4600_ai_query_range_info(me_subdevice_t * subdevice,
112 int range,
113 int *unit,
114 int *min, int *max, int *maxdata);
115static int me4600_ai_query_timer(me_subdevice_t * subdevice,
116 int timer,
117 int *base_frequency,
118 long long *min_ticks, long long *max_ticks);
119static int me4600_ai_query_number_channels(me_subdevice_t * subdevice,
120 int *number);
121static int me4600_ai_query_subdevice_type(me_subdevice_t * subdevice,
122 int *type, int *subtype);
123static int me4600_ai_query_subdevice_caps(me_subdevice_t * subdevice,
124 int *caps);
125static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
126 int cap, int *args, int count);
127
128#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
129static irqreturn_t me4600_ai_isr(int irq, void *dev_id);
130#else
131static irqreturn_t me4600_ai_isr(int irq, void *dev_id, struct pt_regs *regs);
132#endif
133
134static int ai_mux_toggler(me4600_ai_subdevice_t * subdevice);
135
136/** Immidiate stop.
137* Reset all IRQ's sources. (block laches)
138* Preserve FIFO
139*/
140static int ai_stop_immediately(me4600_ai_subdevice_t * instance);
141
142/** Immidiate stop.
143* Reset all IRQ's sources. (block laches)
144* Reset data FIFO
145*/
146void inline ai_stop_isr(me4600_ai_subdevice_t * instance);
147
148/** Interrupt logics.
149* Read datas
150* Reset latches
151*/
152void ai_limited_isr(me4600_ai_subdevice_t * instance, const uint32_t irq_status,
153 const uint32_t ctrl_status);
154void ai_infinite_isr(me4600_ai_subdevice_t * instance,
155 const uint32_t irq_status, const uint32_t ctrl_status);
156
157/** Last chunck of datas. We must reschedule sample counter.
158* Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts.
159* When threshold is wrongly set some IRQ are lost.(!!!)
160*/
161void inline ai_reschedule_SC(me4600_ai_subdevice_t * instance);
162
163/** Read datas from FIFO and copy them to buffer */
164static int inline ai_read_data(me4600_ai_subdevice_t * instance,
165 const int count);
166
167/** Copy rest of data from fifo to circular buffer.*/
168static int inline ai_read_data_pooling(me4600_ai_subdevice_t * instance);
169
170/** Set ISM to next state for infinite data aqusation mode*/
171void inline ai_infinite_ISM(me4600_ai_subdevice_t * instance);
172
173/** Set ISM to next state for define amount of data aqusation mode*/
174void inline ai_limited_ISM(me4600_ai_subdevice_t * instance,
175 uint32_t irq_status);
176
177/** Set ISM to next stage for limited mode */
178void inline ai_data_acquisition_logic(me4600_ai_subdevice_t * instance);
179
180#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
181static void me4600_ai_work_control_task(void *subdevice);
182#else
183static void me4600_ai_work_control_task(struct work_struct *work);
184#endif
185
186/* Definitions
187 */
188
189me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base,
190 unsigned int channels,
191 unsigned int ranges,
192 int isolated,
193 int sh,
194 int irq,
195 spinlock_t * ctrl_reg_lock,
196 struct workqueue_struct *me4600_wq)
197{
198 me4600_ai_subdevice_t *subdevice;
199 int err;
200 unsigned int i;
201
202 PDEBUG("executed. idx=0\n");
203
204 // Allocate memory for subdevice instance.
205 subdevice = kmalloc(sizeof(me4600_ai_subdevice_t), GFP_KERNEL);
206
207 if (!subdevice) {
208 PERROR("Cannot get memory for subdevice instance.\n");
209 return NULL;
210 }
211
212 memset(subdevice, 0, sizeof(me4600_ai_subdevice_t));
213
214 // Initialize subdevice base class.
215 err = me_subdevice_init(&subdevice->base);
216
217 if (err) {
218 PERROR("Cannot initialize subdevice base class instance.\n");
219 kfree(subdevice);
220 return NULL;
221 }
222 // Initialize spin locks.
223 spin_lock_init(&subdevice->subdevice_lock);
224
225 subdevice->ctrl_reg_lock = ctrl_reg_lock;
226
227 // Initialize circular buffer.
228 subdevice->circ_buf.mask = ME4600_AI_CIRC_BUF_COUNT - 1;
229
230 subdevice->circ_buf.buf =
231 (void *)__get_free_pages(GFP_KERNEL, ME4600_AI_CIRC_BUF_SIZE_ORDER);
232 PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf,
233 ME4600_AI_CIRC_BUF_SIZE);
234
235 if (!subdevice->circ_buf.buf) {
236 PERROR("Cannot get circular buffer.\n");
237 me_subdevice_deinit((me_subdevice_t *) subdevice);
238 kfree(subdevice);
239 return NULL;
240 }
241
242 memset(subdevice->circ_buf.buf, 0, ME4600_AI_CIRC_BUF_SIZE);
243 subdevice->circ_buf.head = 0;
244 subdevice->circ_buf.tail = 0;
245 subdevice->status = ai_status_none;
246
247 // Initialize wait queue.
248 init_waitqueue_head(&subdevice->wait_queue);
249
250 // Save the number of channels.
251 subdevice->channels = channels;
252
253 /* Initialize the single config entries to reset values */
254 for (i = 0; i < channels; i++) {
255 subdevice->single_config[i].status = ME_SINGLE_CHANNEL_NOT_CONFIGURED; //not configured
256 }
257
258 // Save if isolated device.
259 subdevice->isolated = isolated;
260
261 // Save if sample and hold is available.
262 subdevice->sh = sh;
263
264 // Set stream config to not configured state.
265 subdevice->fifo_irq_threshold = 0;
266 subdevice->data_required = 0;
267 subdevice->chan_list_len = 0;
268
269 // Initialize registers addresses.
270 subdevice->ctrl_reg = reg_base + ME4600_AI_CTRL_REG;
271 subdevice->status_reg = reg_base + ME4600_AI_STATUS_REG;
272 subdevice->channel_list_reg = reg_base + ME4600_AI_CHANNEL_LIST_REG;
273 subdevice->data_reg = reg_base + ME4600_AI_DATA_REG;
274 subdevice->chan_timer_reg = reg_base + ME4600_AI_CHAN_TIMER_REG;
275 subdevice->chan_pre_timer_reg = reg_base + ME4600_AI_CHAN_PRE_TIMER_REG;
276 subdevice->scan_timer_low_reg = reg_base + ME4600_AI_SCAN_TIMER_LOW_REG;
277 subdevice->scan_timer_high_reg =
278 reg_base + ME4600_AI_SCAN_TIMER_HIGH_REG;
279 subdevice->scan_pre_timer_low_reg =
280 reg_base + ME4600_AI_SCAN_PRE_TIMER_LOW_REG;
281 subdevice->scan_pre_timer_high_reg =
282 reg_base + ME4600_AI_SCAN_PRE_TIMER_HIGH_REG;
283 subdevice->start_reg = reg_base + ME4600_AI_START_REG;
284 subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
285 subdevice->sample_counter_reg = reg_base + ME4600_AI_SAMPLE_COUNTER_REG;
286#ifdef MEDEBUG_DEBUG_REG
287 subdevice->reg_base = reg_base;
288#endif
289
290 // Initialize ranges.
291 subdevice->ranges_len = ranges;
292 subdevice->ranges[0].min = -10E6;
293 subdevice->ranges[0].max = 9999694;
294
295 subdevice->ranges[1].min = 0;
296 subdevice->ranges[1].max = 9999847;
297
298 subdevice->ranges[2].min = -25E5;
299 subdevice->ranges[2].max = 2499923;
300
301 subdevice->ranges[3].min = 0;
302 subdevice->ranges[3].max = 2499961;
303
304 // We have to switch the mux in order to get it work correctly.
305 ai_mux_toggler(subdevice);
306
307 // Register interrupt service routine.
308 subdevice->irq = irq;
309 if (request_irq(subdevice->irq, me4600_ai_isr,
310#ifdef IRQF_DISABLED
311 IRQF_DISABLED | IRQF_SHARED,
312#else
313 SA_INTERRUPT | SA_SHIRQ,
314#endif
315 ME4600_NAME, subdevice)) {
316 PERROR("Cannot register interrupt service routine.\n");
317 me_subdevice_deinit((me_subdevice_t *) subdevice);
318 free_pages((unsigned long)subdevice->circ_buf.buf,
319 ME4600_AI_CIRC_BUF_SIZE_ORDER);
320 subdevice->circ_buf.buf = NULL;
321 kfree(subdevice);
322 return NULL;
323 }
324 PINFO("Registered irq=%d.\n", subdevice->irq);
325
326 // Override base class methods.
327 subdevice->base.me_subdevice_destructor = me4600_ai_destructor;
328 subdevice->base.me_subdevice_io_reset_subdevice =
329 me4600_ai_io_reset_subdevice;
330 subdevice->base.me_subdevice_io_single_config =
331 me4600_ai_io_single_config;
332 subdevice->base.me_subdevice_io_single_read = me4600_ai_io_single_read;
333 subdevice->base.me_subdevice_io_stream_config =
334 me4600_ai_io_stream_config;
335 subdevice->base.me_subdevice_io_stream_new_values =
336 me4600_ai_io_stream_new_values;
337 subdevice->base.me_subdevice_io_stream_read = me4600_ai_io_stream_read;
338 subdevice->base.me_subdevice_io_stream_start =
339 me4600_ai_io_stream_start;
340 subdevice->base.me_subdevice_io_stream_status =
341 me4600_ai_io_stream_status;
342 subdevice->base.me_subdevice_io_stream_stop = me4600_ai_io_stream_stop;
343 subdevice->base.me_subdevice_query_number_channels =
344 me4600_ai_query_number_channels;
345 subdevice->base.me_subdevice_query_subdevice_type =
346 me4600_ai_query_subdevice_type;
347 subdevice->base.me_subdevice_query_subdevice_caps =
348 me4600_ai_query_subdevice_caps;
349 subdevice->base.me_subdevice_query_subdevice_caps_args =
350 me4600_ai_query_subdevice_caps_args;
351 subdevice->base.me_subdevice_query_range_by_min_max =
352 me4600_ai_query_range_by_min_max;
353 subdevice->base.me_subdevice_query_number_ranges =
354 me4600_ai_query_number_ranges;
355 subdevice->base.me_subdevice_query_range_info =
356 me4600_ai_query_range_info;
357 subdevice->base.me_subdevice_query_timer = me4600_ai_query_timer;
358
359 // Prepare work queue.
360 subdevice->me4600_workqueue = me4600_wq;
361
362/* workqueue API changed in kernel 2.6.20 */
363#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
364 INIT_WORK(&subdevice->ai_control_task, me4600_ai_work_control_task,
365 (void *)subdevice);
366#else
367 INIT_DELAYED_WORK(&subdevice->ai_control_task,
368 me4600_ai_work_control_task);
369#endif
370
371 return subdevice;
372}
373
374static void me4600_ai_destructor(struct me_subdevice *subdevice)
375{
376 me4600_ai_subdevice_t *instance;
377
378 instance = (me4600_ai_subdevice_t *) subdevice;
379
380 PDEBUG("executed. idx=0\n");
381
382 instance->ai_control_task_flag = 0;
383 // Reset subdevice to asure clean exit.
384 me4600_ai_io_reset_subdevice(subdevice, NULL,
385 ME_IO_RESET_SUBDEVICE_NO_FLAGS);
386
387 // Remove any tasks from work queue. This is paranoic because it was done allready in reset().
388 if (!cancel_delayed_work(&instance->ai_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue.
389 set_current_state(TASK_INTERRUPTIBLE);
390 schedule_timeout(2);
391 }
392
393 free_irq(instance->irq, instance);
394 free_pages((unsigned long)instance->circ_buf.buf,
395 ME4600_AI_CIRC_BUF_SIZE_ORDER);
396 me_subdevice_deinit(&instance->base);
397 kfree(instance);
398}
399
400static int me4600_ai_io_reset_subdevice(me_subdevice_t * subdevice,
401 struct file *filep, int flags)
402{
403 me4600_ai_subdevice_t *instance;
404 int err = ME_ERRNO_SUCCESS;
405 volatile uint32_t ctrl;
406 unsigned long status;
407 const int timeout = HZ / 10; //100ms
408 int i;
409
410 PDEBUG("executed. idx=0\n");
411
412 if (flags) {
413 PERROR("Invalid flag specified.\n");
414 return ME_ERRNO_INVALID_FLAGS;
415 }
416
417 instance = (me4600_ai_subdevice_t *) subdevice;
418
419 ME_SUBDEVICE_ENTER;
420
421 instance->ai_control_task_flag = 0;
422 instance->status = ai_status_none;
423
424 for (i = 0; i <= timeout; i++) {
425 spin_lock_irqsave(instance->ctrl_reg_lock, status);
426 ctrl = inl(instance->ctrl_reg);
427 //Stop DMA
428 ctrl &= ~ME4600_AI_CTRL_RPCI_FIFO;
429 // Stop all actions. No conditions!
430 ctrl &= ~ME4600_AI_CTRL_BIT_STOP;
431 ctrl |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
432
433 outl(ctrl, instance->ctrl_reg);
434 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
435 instance->reg_base,
436 instance->ctrl_reg - instance->reg_base, ctrl);
437 spin_unlock_irqrestore(instance->ctrl_reg_lock, status);
438
439 if (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM))
440 break;
441
442 set_current_state(TASK_INTERRUPTIBLE);
443 schedule_timeout(1);
444 }
445
446 if (i > timeout) {
447 PERROR("FSM is still busy.\n");
448 ME_SUBDEVICE_EXIT;
449 return ME_ERRNO_INTERNAL;
450 }
451
452 spin_lock_irqsave(instance->ctrl_reg_lock, status);
453 ctrl = inl(instance->ctrl_reg);
454 // Clear all features. Dissable interrupts.
455 ctrl &= ~(ME4600_AI_CTRL_BIT_STOP
456 | ME4600_AI_CTRL_BIT_LE_IRQ
457 | ME4600_AI_CTRL_BIT_HF_IRQ | ME4600_AI_CTRL_BIT_SC_IRQ);
458 ctrl |= (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP
459 | ME4600_AI_CTRL_BIT_LE_IRQ_RESET
460 | ME4600_AI_CTRL_BIT_HF_IRQ_RESET
461 | ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
462
463 outl(ctrl, instance->ctrl_reg);
464 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
465 instance->ctrl_reg - instance->reg_base, ctrl);
466 spin_unlock_irqrestore(instance->ctrl_reg_lock, status);
467
468 outl(ME4600_AI_MIN_CHAN_TICKS - 1, instance->chan_timer_reg);
469 PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%llx\n",
470 instance->reg_base,
471 instance->chan_timer_reg - instance->reg_base,
472 ME4600_AI_MIN_CHAN_TICKS);
473 outl(ME4600_AI_MIN_ACQ_TICKS - 1, instance->chan_pre_timer_reg);
474 PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%llx\n",
475 instance->reg_base,
476 instance->chan_pre_timer_reg - instance->reg_base,
477 ME4600_AI_MIN_ACQ_TICKS);
478 outl(0, instance->scan_timer_low_reg);
479 PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
480 instance->reg_base,
481 instance->scan_timer_low_reg - instance->reg_base, 0);
482 outl(0, instance->scan_timer_high_reg);
483 PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
484 instance->reg_base,
485 instance->scan_timer_high_reg - instance->reg_base, 0);
486 outl(0, instance->scan_pre_timer_low_reg);
487 PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
488 instance->reg_base,
489 instance->scan_pre_timer_low_reg - instance->reg_base, 0);
490 outl(0, instance->scan_pre_timer_high_reg);
491 PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
492 instance->reg_base,
493 instance->scan_pre_timer_high_reg - instance->reg_base, 0);
494 outl(0xEFFFFFFF, instance->sample_counter_reg);
495 PDEBUG_REG("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
496 instance->reg_base,
497 instance->sample_counter_reg - instance->reg_base,
498 0xEFFFFFFF);
499
500 instance->circ_buf.head = 0;
501 instance->circ_buf.tail = 0;
502
503 instance->fifo_irq_threshold = 0;
504 instance->data_required = 0;
505 instance->chan_list_len = 0;
506
507 // Initialize the single config entries to reset values.
508 for (i = 0; i < instance->channels; i++) {
509 instance->single_config[i].status =
510 ME_SINGLE_CHANNEL_NOT_CONFIGURED;
511 }
512 instance->status = ai_status_none;
513
514 //Signal reset if user is on wait.
515 wake_up_interruptible_all(&instance->wait_queue);
516
517 ME_SUBDEVICE_EXIT;
518
519 return err;
520}
521
522static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
523 struct file *filep,
524 int channel,
525 int single_config,
526 int ref,
527 int trig_chan,
528 int trig_type, int trig_edge, int flags)
529{
530 me4600_ai_subdevice_t *instance;
531 int err = ME_ERRNO_SUCCESS;
532 unsigned long cpu_flags;
533 int i;
534
535 instance = (me4600_ai_subdevice_t *) subdevice;
536
537 PDEBUG("executed. idx=0\n");
538
539 if (flags & ~ME_IO_SINGLE_CONFIG_CONTINUE) {
540 PERROR("Invalid flag specified.\n");
541 return ME_ERRNO_INVALID_FLAGS;
542 }
543
544 switch (trig_type) {
545 case ME_TRIG_TYPE_SW:
546 if (trig_edge != ME_TRIG_EDGE_NONE) {
547 PERROR
548 ("Invalid trigger edge. Software trigger has not edge.\n");
549 return ME_ERRNO_INVALID_TRIG_EDGE;
550 }
551 break;
552
553 case ME_TRIG_TYPE_EXT_ANALOG:
554 if (instance->channels <= 16) //Only versions with 32 channels have analog trigger (4670 and 4680)
555 {
556 PERROR("Invalid trigger type specified.\n");
557 return ME_ERRNO_INVALID_TRIG_TYPE;
558 }
559
560 case ME_TRIG_TYPE_EXT_DIGITAL:
561 if ((trig_edge != ME_TRIG_EDGE_ANY)
562 && (trig_edge != ME_TRIG_EDGE_RISING)
563 && (trig_edge != ME_TRIG_EDGE_FALLING)) {
564 PERROR("Invalid trigger edge specified.\n");
565 return ME_ERRNO_INVALID_TRIG_EDGE;
566 }
567 break;
568
569 default:
570 PERROR("Invalid trigger type specified.\n");
571 return ME_ERRNO_INVALID_TRIG_TYPE;
572 }
573
574 if (trig_chan != ME_TRIG_CHAN_DEFAULT) {
575 PERROR("Invalid trigger channel specified.\n");
576 return ME_ERRNO_INVALID_TRIG_CHAN;
577 }
578
579 if ((single_config < 0) || (single_config >= instance->ranges_len)) {
580 PERROR("Invalid single config specified.\n");
581 return ME_ERRNO_INVALID_SINGLE_CONFIG;
582 }
583
584 if ((ref != ME_REF_AI_GROUND) && (ref != ME_REF_AI_DIFFERENTIAL)) {
585 PERROR("Invalid analog reference specified.\n");
586 return ME_ERRNO_INVALID_REF;
587 }
588
589 if ((single_config % 2) && (ref != ME_REF_AI_GROUND)) {
590 PERROR("Invalid analog reference specified.\n");
591 return ME_ERRNO_INVALID_REF;
592 }
593
594 if ((ref == ME_REF_AI_DIFFERENTIAL)
595 && ((instance->channels == 16) || (channel >= 16))) {
596 PERROR("Invalid analog reference specified.\n");
597 return ME_ERRNO_INVALID_REF;
598 }
599
600 if (channel < 0) {
601 PERROR("Invalid channel number specified.\n");
602 return ME_ERRNO_INVALID_CHANNEL;
603 }
604
605 if (channel >= instance->channels) {
606 PERROR("Invalid channel number specified.\n");
607 return ME_ERRNO_INVALID_CHANNEL;
608 }
609
610 ME_SUBDEVICE_ENTER;
611
612 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
613 //Prepare data entry.
614 // Common for all modes.
615 instance->single_config[channel].entry =
616 channel | ME4600_AI_LIST_LAST_ENTRY;
617
618 if (ref == ME_REF_AI_DIFFERENTIAL) { // ME_REF_AI_DIFFERENTIAL
619 instance->single_config[channel].entry |=
620 ME4600_AI_LIST_INPUT_DIFFERENTIAL;
621 }
622/*
623 // ME4600_AI_LIST_INPUT_SINGLE_ENDED = 0x0000
624 // 'entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED' <== Do nothing. Removed.
625 else
626 {// ME_REF_AI_GROUND
627 instance->single_config[channel].entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED;
628 }
629*/
630 switch (single_config) {
631 case 0: //-10V..10V
632/*
633 // ME4600_AI_LIST_RANGE_BIPOLAR_10 = 0x0000
634 // 'entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10' <== Do nothing. Removed.
635 instance->single_config[channel].entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10;
636*/ break;
637
638 case 1: //0V..10V
639 instance->single_config[channel].entry |=
640 ME4600_AI_LIST_RANGE_UNIPOLAR_10;
641 break;
642
643 case 2: //-2.5V..2.5V
644 instance->single_config[channel].entry |=
645 ME4600_AI_LIST_RANGE_BIPOLAR_2_5;
646 break;
647
648 case 3: //0V..2.5V
649 instance->single_config[channel].entry |=
650 ME4600_AI_LIST_RANGE_UNIPOLAR_2_5;
651 break;
652 }
653
654 // Prepare control register.
655 // Common for all modes.
656 instance->single_config[channel].ctrl =
657 ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
658
659 switch (trig_type) {
660 case ME_TRIG_TYPE_SW:
661 // Nothing to set.
662 break;
663
664 case ME_TRIG_TYPE_EXT_ANALOG:
665 instance->single_config[channel].ctrl |=
666 ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG;
667
668 case ME_TRIG_TYPE_EXT_DIGITAL:
669 instance->single_config[channel].ctrl |=
670 ME4600_AI_CTRL_BIT_EX_TRIG;
671 break;
672 }
673
674 switch (trig_edge) {
675 case ME_TRIG_EDGE_RISING:
676 // Nothing to set.
677 break;
678
679 case ME_TRIG_EDGE_ANY:
680 instance->single_config[channel].ctrl |=
681 ME4600_AI_CTRL_BIT_EX_TRIG_BOTH;
682
683 case ME_TRIG_EDGE_FALLING:
684 instance->single_config[channel].ctrl |=
685 ME4600_AI_CTRL_BIT_EX_TRIG_FALLING;
686 break;
687 }
688
689 // Enable this channel
690 instance->single_config[channel].status = ME_SINGLE_CHANNEL_CONFIGURED;
691
692 // Copy this settings to other outputs.
693 if (flags == ME_IO_SINGLE_CONFIG_CONTINUE) {
694 for (i = channel + 1; i < instance->channels; i++) {
695 instance->single_config[i].ctrl =
696 instance->single_config[channel].ctrl;
697 instance->single_config[i].entry =
698 instance->single_config[channel].entry;
699 instance->single_config[i].status =
700 ME_SINGLE_CHANNEL_CONFIGURED;
701 }
702 }
703
704 instance->status = ai_status_single_configured;
705 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
706
707 ME_SUBDEVICE_EXIT;
708
709 return err;
710}
711
712static int me4600_ai_io_single_read(me_subdevice_t * subdevice,
713 struct file *filep,
714 int channel,
715 int *value, int time_out, int flags)
716{
717 me4600_ai_subdevice_t *instance;
718 volatile uint32_t tmp;
719 volatile uint32_t val;
720 unsigned long cpu_flags;
721 int err = ME_ERRNO_SUCCESS;
722
723 unsigned long j;
724 unsigned long delay = 0;
725
726 PDEBUG("executed. idx=0\n");
727
728 instance = (me4600_ai_subdevice_t *) subdevice;
729
730 if (flags) {
731 PERROR("Invalid flag specified.\n");
732 return ME_ERRNO_INVALID_FLAGS;
733 }
734
735 if (instance->status != ai_status_single_configured) {
736 PERROR("Subdevice not configured to work in single mode!\n");
737 return ME_ERRNO_PREVIOUS_CONFIG;
738 }
739
740 if ((channel > instance->channels) || (channel < 0)) {
741 PERROR("Invalid channel specified.\n");
742 return ME_ERRNO_INVALID_CHANNEL;
743 }
744
745 if (time_out < 0) {
746 PERROR("Invalid timeout specified.\n");
747 return ME_ERRNO_INVALID_TIMEOUT;
748 }
749
750 if (instance->single_config[channel].status !=
751 ME_SINGLE_CHANNEL_CONFIGURED) {
752 PERROR("Channel is not configured to work in single mode!\n");
753 return ME_ERRNO_PREVIOUS_CONFIG;
754 }
755
756 if (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) {
757 PERROR("Subdevice is busy.\n");
758 return ME_ERRNO_SUBDEVICE_BUSY;
759 }
760
761 ME_SUBDEVICE_ENTER;
762
763 // Cancel control task
764 PDEBUG("Cancel control task.\n");
765 instance->ai_control_task_flag = 0;
766 cancel_delayed_work(&instance->ai_control_task);
767
768 if (time_out) {
769 delay = (time_out * HZ) / 1000;
770
771 if (delay == 0)
772 delay = 1;
773 }
774
775 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
776
777 // Mark that StreamConfig is removed.
778 instance->chan_list_len = 0;
779
780 spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
781 /// @note Imprtant: Preserve EXT IRQ settings.
782 tmp = inl(instance->ctrl_reg);
783 // Clear FIFOs and dissable interrupts
784 tmp &=
785 ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
786
787 tmp &=
788 ~(ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_HF_IRQ |
789 ME4600_AI_CTRL_BIT_LE_IRQ);
790 tmp |=
791 ME4600_AI_CTRL_BIT_SC_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
792 ME4600_AI_CTRL_BIT_LE_IRQ_RESET;
793
794 tmp |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
795 outl(tmp, instance->ctrl_reg);
796 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
797 instance->ctrl_reg - instance->reg_base, tmp);
798
799 outl(0, instance->scan_pre_timer_low_reg);
800 PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
801 instance->reg_base,
802 instance->scan_pre_timer_low_reg - instance->reg_base, 0);
803 outl(0, instance->scan_pre_timer_high_reg);
804 PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
805 instance->reg_base,
806 instance->scan_pre_timer_high_reg - instance->reg_base, 0);
807 outl(0, instance->scan_timer_low_reg);
808 PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
809 instance->reg_base,
810 instance->scan_timer_low_reg - instance->reg_base, 0);
811 outl(0, instance->scan_timer_high_reg);
812 PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
813 instance->reg_base,
814 instance->scan_timer_high_reg - instance->reg_base, 0);
815 outl(65, instance->chan_timer_reg);
816 PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
817 instance->reg_base,
818 instance->chan_timer_reg - instance->reg_base, 65);
819 outl(65, instance->chan_pre_timer_reg);
820 PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
821 instance->reg_base,
822 instance->chan_pre_timer_reg - instance->reg_base, 65);
823
824 //Reactive FIFOs. Enable work.
825 tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
826 outl(tmp, instance->ctrl_reg);
827 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
828 instance->ctrl_reg - instance->reg_base, tmp);
829
830 outl(instance->single_config[channel].entry,
831 instance->channel_list_reg);
832 PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
833 instance->reg_base,
834 instance->channel_list_reg - instance->reg_base,
835 instance->single_config[channel].entry);
836
837 // Preserve EXT IRQ settings.
838 tmp &= (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
839 outl(instance->single_config[channel].ctrl | tmp, instance->ctrl_reg);
840 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
841 instance->ctrl_reg - instance->reg_base,
842 instance->single_config[channel].ctrl | tmp);
843
844 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
845
846 if (!(instance->single_config[channel].ctrl & ME4600_AI_CTRL_BIT_EX_TRIG)) { // Software start
847 inl(instance->start_reg);
848 PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
849 instance->start_reg - instance->reg_base);
850
851 delay = 2;
852 }
853
854 j = jiffies;
855
856 while (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_EF_DATA)) {
857 if (delay && ((jiffies - j) >= delay)) {
858 if (!(instance->single_config[channel].ctrl & ME4600_AI_CTRL_BIT_EX_TRIG)) { // Software start.
859 PERROR("Value not available after wait.\n");
860 err = ME_ERRNO_INTERNAL;
861 } else { // External start.
862 PERROR("Timeout reached.\n");
863 err = ME_ERRNO_TIMEOUT;
864 }
865 break;
866 }
867 // Wait
868 set_current_state(TASK_INTERRUPTIBLE);
869 schedule_timeout(1);
870
871 if (signal_pending(current)) {
872 PERROR
873 ("Wait on external trigger interrupted by signal.\n");
874 err = ME_ERRNO_SIGNAL;
875 break;
876 }
877
878 if (instance->status != ai_status_single_configured) {
879 PERROR("Wait interrupted by reset.\n");
880 err = ME_ERRNO_CANCELLED;
881 break;
882 }
883 }
884
885 // Read value.
886 if (!err) {
887 val = inl(instance->data_reg) ^ 0x8000;
888 PDEBUG_REG("data_reg inl(0x%lX+0x%lX)=0x%x\n",
889 instance->reg_base,
890 instance->data_reg - instance->reg_base, val);
891 *value = val & ME4600_AI_MAX_DATA;
892 } else {
893 *value = 0xFFFFFFFF;
894 }
895
896 // Restore settings.
897 spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
898 tmp = inl(instance->ctrl_reg);
899 // Clear FIFOs and dissable interrupts.
900 tmp &=
901 ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
902 tmp |= ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_HF_IRQ;
903 tmp |=
904 ME4600_AI_CTRL_BIT_SC_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
905 ME4600_AI_CTRL_BIT_LE_IRQ_RESET | ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
906 outl(tmp, instance->ctrl_reg);
907 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
908 instance->ctrl_reg - instance->reg_base, tmp);
909 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
910
911 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
912
913 ME_SUBDEVICE_EXIT;
914
915 return err;
916}
917
918static int me4600_ai_io_stream_config(me_subdevice_t * subdevice,
919 struct file *filep,
920 meIOStreamConfig_t * config_list,
921 int count,
922 meIOStreamTrigger_t * trigger,
923 int fifo_irq_threshold, int flags)
924{
925 me4600_ai_subdevice_t *instance;
926 int err = ME_ERRNO_SUCCESS;
927 int i; // internal multipurpose variable
928 unsigned long long data_required;
929
930 volatile uint32_t entry;
931 volatile uint32_t ctrl = ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
932 volatile uint32_t tmp; // use when current copy of register's value needed
933 unsigned long cpu_flags;
934
935 uint64_t acq_ticks;
936 uint64_t scan_ticks;
937 uint64_t conv_ticks;
938 unsigned int acq_start_ticks_low = trigger->iAcqStartTicksLow;
939 unsigned int acq_start_ticks_high = trigger->iAcqStartTicksHigh;
940 unsigned int scan_start_ticks_low = trigger->iScanStartTicksLow;
941 unsigned int scan_start_ticks_high = trigger->iScanStartTicksHigh;
942 unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
943 unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
944
945 PDEBUG("executed. idx=0\n");
946
947 instance = (me4600_ai_subdevice_t *) subdevice;
948
949 if (flags) {
950 PERROR("Invalid flag specified.\n");
951 return ME_ERRNO_INVALID_FLAGS;
952 }
953
954 ME_SUBDEVICE_ENTER
955 // Convert ticks to 64 bit long values
956 acq_ticks =
957 (uint64_t) acq_start_ticks_low +
958 ((uint64_t) acq_start_ticks_high << 32);
959 scan_ticks =
960 (uint64_t) scan_start_ticks_low +
961 ((uint64_t) scan_start_ticks_high << 32);
962 conv_ticks =
963 (uint64_t) conv_start_ticks_low +
964 ((uint64_t) conv_start_ticks_high << 32);
965
966 // Check settings - begin
967 switch (trigger->iAcqStartTrigType) {
968 case ME_TRIG_TYPE_SW:
969 case ME_TRIG_TYPE_EXT_DIGITAL:
970 case ME_TRIG_TYPE_EXT_ANALOG:
971 break;
972
973 default:
974 PERROR("Invalid acquisition start trigger type specified.\n");
975 err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
976 goto ERROR;
977 break;
978 }
979
980 if ((trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW)
981 && (trigger->iAcqStartTrigEdge != ME_TRIG_EDGE_NONE)) {
982 PERROR("Invalid acquisition start trigger edge specified.\n");
983 err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
984 goto ERROR;
985 }
986
987 if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_SW) {
988 switch (trigger->iAcqStartTrigEdge) {
989 case ME_TRIG_EDGE_RISING:
990 case ME_TRIG_EDGE_FALLING:
991 case ME_TRIG_EDGE_ANY:
992 break;
993
994 default:
995 PERROR
996 ("Invalid acquisition start trigger edge specified.\n");
997 err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
998 goto ERROR;
999 break;
1000 }
1001 }
1002
1003 if (trigger->iAcqStartTrigChan != ME_TRIG_CHAN_DEFAULT) {
1004 PERROR
1005 ("Invalid acquisition start trigger channel specified.\n");
1006 err = ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
1007 goto ERROR;
1008 }
1009
1010 if ((acq_ticks < ME4600_AI_MIN_ACQ_TICKS)
1011 || (acq_ticks > ME4600_AI_MAX_ACQ_TICKS)) {
1012 PERROR
1013 ("Invalid acquisition start trigger argument specified.\n");
1014 err = ME_ERRNO_INVALID_ACQ_START_ARG;
1015 goto ERROR;
1016 }
1017
1018 switch (trigger->iScanStartTrigType) {
1019
1020 case ME_TRIG_TYPE_TIMER:
1021 if ((scan_ticks < ME4600_AI_MIN_SCAN_TICKS)
1022 || (scan_ticks > ME4600_AI_MAX_SCAN_TICKS)
1023 || (scan_ticks < count * conv_ticks)
1024 ) {
1025 PERROR("Invalid scan start argument specified.\n");
1026 err = ME_ERRNO_INVALID_SCAN_START_ARG;
1027 goto ERROR;
1028 }
1029 break;
1030
1031 case ME_TRIG_TYPE_EXT_DIGITAL:
1032 if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_DIGITAL) {
1033 PERROR
1034 ("Invalid scan start trigger type specified (Acq is HW digital)\n");
1035 err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
1036 goto ERROR;
1037 }
1038 break;
1039
1040 case ME_TRIG_TYPE_EXT_ANALOG:
1041 if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_ANALOG) {
1042 PERROR
1043 ("Invalid scan start trigger type specified (Acq is HW analog)\n");
1044 err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
1045 goto ERROR;
1046 }
1047 break;
1048
1049 case ME_TRIG_TYPE_FOLLOW:
1050 break;
1051
1052 default:
1053 PERROR("Invalid scan start trigger type specified.\n");
1054 err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
1055 goto ERROR;
1056 break;
1057 }
1058
1059 switch (trigger->iConvStartTrigType) {
1060
1061 case ME_TRIG_TYPE_TIMER:
1062 if ((conv_ticks < ME4600_AI_MIN_CHAN_TICKS)
1063 || (conv_ticks > ME4600_AI_MAX_CHAN_TICKS)) {
1064 PERROR
1065 ("Invalid conv start trigger argument specified.\n");
1066 err = ME_ERRNO_INVALID_CONV_START_ARG;
1067 goto ERROR;
1068 }
1069 break;
1070
1071 case ME_TRIG_TYPE_EXT_DIGITAL:
1072 if ((trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW)
1073 || (trigger->iAcqStartTrigType !=
1074 ME_TRIG_TYPE_EXT_DIGITAL)) {
1075 PERROR("Invalid conv start trigger type specified.\n");
1076 err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
1077 goto ERROR;
1078 }
1079 break;
1080
1081 case ME_TRIG_TYPE_EXT_ANALOG:
1082 if ((trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW)
1083 || (trigger->iAcqStartTrigType !=
1084 ME_TRIG_TYPE_EXT_ANALOG)) {
1085 PERROR("Invalid conv start trigger type specified.\n");
1086 err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
1087 goto ERROR;
1088 }
1089 break;
1090
1091 default:
1092 PERROR("Invalid conv start trigger type specified.\n");
1093 err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
1094 goto ERROR;
1095
1096 break;
1097 }
1098/**
1099* Aceptable settings:
1100* iScanStopTrigType : iAcqStopTrigType
1101*
1102* ME_TRIG_TYPE_NONE : ME_TRIG_TYPE_NONE -> infinite count with manual stop
1103* ME_TRIG_TYPE_NONE : ME_TRIG_TYPE_COUNT -> stop after getting iScanStopCount list of values (iScanStopCount * count)
1104* ME_TRIG_TYPE_COUNT : ME_TRIG_TYPE_FOLLOW -> stop after getting iAcqStopCount values (it can stops in midle of the list)
1105*/
1106 switch (trigger->iScanStopTrigType) {
1107
1108 case ME_TRIG_TYPE_NONE:
1109 break;
1110
1111 case ME_TRIG_TYPE_COUNT:
1112 if (trigger->iScanStopCount <= 0) {
1113 PERROR("Invalid scan stop argument specified.\n");
1114 err = ME_ERRNO_INVALID_SCAN_STOP_ARG;
1115 goto ERROR;
1116 }
1117 break;
1118
1119 default:
1120 PERROR("Invalid scan stop trigger type specified.\n");
1121 err = ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
1122 goto ERROR;
1123 break;
1124 }
1125
1126 switch (trigger->iAcqStopTrigType) {
1127
1128 case ME_TRIG_TYPE_NONE:
1129 if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
1130 PERROR("Invalid acq stop trigger type specified.\n");
1131 err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1132 goto ERROR;
1133 }
1134 break;
1135
1136 case ME_TRIG_TYPE_FOLLOW:
1137 if (trigger->iScanStopTrigType != ME_TRIG_TYPE_COUNT) {
1138 PERROR("Invalid acq stop trigger type specified.\n");
1139 err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1140 goto ERROR;
1141 }
1142 break;
1143
1144 case ME_TRIG_TYPE_COUNT:
1145 if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
1146 PERROR("Invalid acq stop trigger type specified.\n");
1147 err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1148 goto ERROR;
1149 }
1150
1151 if (trigger->iAcqStopCount <= 0) {
1152 PERROR
1153 ("Invalid acquisition or scan stop argument specified.\n");
1154 err = ME_ERRNO_INVALID_ACQ_STOP_ARG;
1155 goto ERROR;
1156 }
1157 break;
1158
1159 default:
1160 PERROR("Invalid acq stop trigger type specified.\n");
1161 err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1162 goto ERROR;
1163 break;
1164 }
1165
1166 if ((count <= 0) || (count > ME4600_AI_LIST_COUNT)) {
1167 PERROR("Invalid channel list count specified.\n");
1168 err = ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
1169 goto ERROR;
1170 }
1171///This is general limitation
1172// if (fifo_irq_threshold < 0 || fifo_irq_threshold >= ME4600_AI_CIRC_BUF_COUNT)
1173///This is limitation from Windows. I use it for compatibility.
1174 if (fifo_irq_threshold < 0
1175 || fifo_irq_threshold >= ME4600_AI_FIFO_COUNT) {
1176 PERROR("Invalid fifo irq threshold specified.\n");
1177 err = ME_ERRNO_INVALID_FIFO_IRQ_THRESHOLD;
1178 goto ERROR;
1179 }
1180
1181 if ((config_list[0].iRef == ME_REF_AI_DIFFERENTIAL)
1182 && (instance->channels == 16)) {
1183 PERROR
1184 ("Differential reference is not available on this subdevice.\n");
1185 err = ME_ERRNO_INVALID_REF;
1186 goto ERROR;
1187 }
1188
1189 if (flags & ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD) {
1190 if (!instance->sh) {
1191 PERROR
1192 ("Sample and hold is not available for this board.\n");
1193 err = ME_ERRNO_INVALID_FLAGS;
1194 goto ERROR;
1195 }
1196 if (config_list[0].iRef == ME_REF_AI_DIFFERENTIAL) {
1197 PERROR
1198 ("Sample and hold is not available in differential mode.\n");
1199 err = ME_ERRNO_INVALID_FLAGS;
1200 goto ERROR;
1201 }
1202 }
1203
1204 for (i = 0; i < count; i++) {
1205 if ((config_list[i].iStreamConfig < 0)
1206 || (config_list[i].iStreamConfig >= instance->ranges_len)) {
1207 PERROR("Invalid stream config specified.\n");
1208 err = ME_ERRNO_INVALID_STREAM_CONFIG;
1209 goto ERROR;
1210 }
1211
1212 if ((config_list[i].iRef != ME_REF_AI_GROUND)
1213 && (config_list[i].iRef != ME_REF_AI_DIFFERENTIAL)) {
1214 PERROR("Invalid references in the list. Ref=0x%x\n",
1215 config_list[i].iRef);
1216 err = ME_ERRNO_INVALID_REF;
1217 goto ERROR;
1218 }
1219
1220 if (config_list[i].iStreamConfig % 2) { // StreamConfig: 1 or 3
1221 if (config_list[i].iRef == ME_REF_AI_DIFFERENTIAL) {
1222 PERROR
1223 ("Only bipolar modes support differential measurement.\n");
1224 err = ME_ERRNO_INVALID_REF;
1225 goto ERROR;
1226 }
1227 }
1228
1229 if (config_list[i].iRef != config_list[0].iRef) {
1230 PERROR
1231 ("Not all references in the configuration list are equal. Ref[0]=0x%x Ref[%d]=0x%x\n",
1232 config_list[0].iRef, i, config_list[i].iRef);
1233 err = ME_ERRNO_INVALID_REF;
1234 goto ERROR;
1235 }
1236
1237 if ((config_list[i].iRef == ME_REF_AI_DIFFERENTIAL)
1238 && (config_list[i].iChannel >= 16)) {
1239 PERROR("Channel not available in differential mode.\n");
1240 err = ME_ERRNO_INVALID_CHANNEL;
1241 goto ERROR;
1242 }
1243
1244 if ((config_list[i].iChannel < 0)
1245 || (config_list[i].iChannel >= instance->channels)) {
1246 PERROR("Invalid channel number specified.\n");
1247 err = ME_ERRNO_INVALID_CHANNEL;
1248 goto ERROR;
1249 }
1250 }
1251
1252 // Check settings - end
1253
1254 //Cancel control task
1255 PDEBUG("Cancel control task.\n");
1256 instance->ai_control_task_flag = 0;
1257 cancel_delayed_work(&instance->ai_control_task);
1258
1259 // Work around from Keith Hartley - begin
1260 if (trigger->iScanStartTrigType == ME_TRIG_TYPE_TIMER) {
1261 if (count == 1) {
1262 // The hardware does not work properly with a non-zero scan time
1263 // if there is only ONE channel in the channel list. In this case
1264 // we must set the scan time to zero and use the channel time.
1265
1266 conv_ticks = scan_ticks;
1267 trigger->iScanStartTrigType = ME_TRIG_TYPE_FOLLOW;
1268 } else if (scan_ticks == count * conv_ticks) {
1269 // Another hardware problem. If the number of scan ticks is
1270 // exactly equal to the number of channel ticks multiplied by
1271 // the number of channels then the sampling rate is reduced
1272 // by half.
1273 trigger->iScanStartTrigType = ME_TRIG_TYPE_FOLLOW;
1274 }
1275 }
1276 // Work around from Keith Hartley - end
1277
1278 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
1279
1280 if (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) {
1281 PERROR("Subdevice is busy.\n");
1282 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
1283 ME_SUBDEVICE_EXIT;
1284 return ME_ERRNO_SUBDEVICE_BUSY;
1285 }
1286
1287 instance->status = ai_status_none;
1288 spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
1289 // Stop all actions. Block all interrupts. Clear (disable) FIFOs.
1290 ctrl =
1291 ME4600_AI_CTRL_BIT_LE_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
1292 ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
1293
1294 tmp = inl(instance->ctrl_reg);
1295 // Preserve EXT IRQ and OFFSET settings. Clean other bits.
1296 tmp &=
1297 (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET |
1298 ME4600_AI_CTRL_BIT_FULLSCALE | ME4600_AI_CTRL_BIT_OFFSET);
1299
1300 // Send it to register.
1301 outl(tmp | ctrl, instance->ctrl_reg);
1302 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1303 instance->ctrl_reg - instance->reg_base, tmp | ctrl);
1304
1305 // Enable channel fifo -> data fifo in stream_start().
1306 ctrl |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO;
1307 outl(tmp | ctrl, instance->ctrl_reg);
1308 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1309 instance->ctrl_reg - instance->reg_base, tmp | ctrl);
1310 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
1311
1312 // Write the channel list
1313 for (i = 0; i < count; i++) {
1314 entry = config_list[i].iChannel;
1315
1316 switch (config_list[i].iStreamConfig) {
1317 case 0: //BIPOLAR 10V
1318/*
1319 // ME4600_AI_LIST_RANGE_BIPOLAR_10 = 0x0000
1320 // 'entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10' <== Do nothing. Removed.
1321 entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10;
1322*/
1323 break;
1324 case 1: //UNIPOLAR 10V
1325 entry |= ME4600_AI_LIST_RANGE_UNIPOLAR_10;
1326 break;
1327 case 2: //BIPOLAR 2.5V
1328 entry |= ME4600_AI_LIST_RANGE_BIPOLAR_2_5;
1329 break;
1330 case 3: //UNIPOLAR 2.5V
1331 entry |= ME4600_AI_LIST_RANGE_UNIPOLAR_2_5;
1332 break;
1333 default:
1334 PERROR_CRITICAL("UNCHECK ERROR in config_list!\n");
1335 PERROR_CRITICAL
1336 ("WRONG range\nPosition:%d Range:0x%04X\n", i,
1337 config_list[i].iStreamConfig);
1338 goto VERIFY_ERROR;
1339 break;
1340 }
1341
1342 switch (config_list[i].iRef) {
1343 case ME_REF_AI_GROUND: //SINGLE ENDED
1344/*
1345 // ME4600_AI_LIST_INPUT_SINGLE_ENDED = 0x0000
1346 // 'entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED' ==> Do nothing. Removed.
1347 entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED;
1348*/ break;
1349 case ME_REF_AI_DIFFERENTIAL: //DIFFERENTIAL
1350 entry |= ME4600_AI_LIST_INPUT_DIFFERENTIAL;
1351 break;
1352 default:
1353 PERROR_CRITICAL("UNCHECK ERROR in config_list!\n");
1354 PERROR_CRITICAL
1355 ("WRONG reference\nPosition:%d Reference:0x%04X\n",
1356 i, config_list[i].iRef);
1357 goto VERIFY_ERROR;
1358 break;
1359 }
1360
1361 //Add last entry flag
1362 if (i == (count - 1)) {
1363 entry |= ME4600_AI_LIST_LAST_ENTRY;
1364 }
1365
1366 outl(entry, instance->channel_list_reg);
1367 PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
1368 instance->reg_base,
1369 instance->channel_list_reg - instance->reg_base,
1370 entry);
1371 }
1372
1373 // Set triggering registers
1374 --acq_ticks;
1375 outl(acq_ticks, instance->chan_pre_timer_reg);
1376 PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%llX\n",
1377 instance->reg_base,
1378 instance->chan_pre_timer_reg - instance->reg_base,
1379 acq_ticks);
1380 outl(acq_ticks, instance->scan_pre_timer_low_reg);
1381 PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%llX\n",
1382 instance->reg_base,
1383 instance->scan_pre_timer_low_reg - instance->reg_base,
1384 acq_ticks & 0xFFFFFFFF);
1385 outl((acq_ticks >> 32), instance->scan_pre_timer_high_reg);
1386 PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%llX\n",
1387 instance->reg_base,
1388 instance->scan_pre_timer_high_reg - instance->reg_base,
1389 (acq_ticks >> 32) & 0xFFFFFFFF);
1390
1391 // Set triggers
1392 switch (trigger->iAcqStartTrigType) {
1393 // Internal
1394 case ME_TRIG_TYPE_SW:
1395 // Nothing to set.
1396 break;
1397
1398 // External
1399 case ME_TRIG_TYPE_EXT_ANALOG:
1400 ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG;
1401 case ME_TRIG_TYPE_EXT_DIGITAL:
1402 ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG;
1403
1404 // External trigger needs edge's definition
1405 switch (trigger->iAcqStartTrigEdge) {
1406 case ME_TRIG_EDGE_RISING:
1407 // Nothing to set.
1408 break;
1409
1410 case ME_TRIG_EDGE_FALLING:
1411 ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG_FALLING;
1412 break;
1413
1414 case ME_TRIG_EDGE_ANY:
1415 ctrl |=
1416 ME4600_AI_CTRL_BIT_EX_TRIG_FALLING |
1417 ME4600_AI_CTRL_BIT_EX_TRIG_BOTH;
1418 break;
1419
1420 default:
1421 PERROR_CRITICAL
1422 ("UNCHECK TRIGGER EDGE in triggers structure!\n");
1423 PERROR_CRITICAL
1424 ("WRONG acquisition start trigger:0x%04X.\n",
1425 trigger->iAcqStartTrigEdge);
1426 err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
1427 goto VERIFY_ERROR;
1428 break;
1429 }
1430 break;
1431
1432 default:
1433 PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n");
1434 PERROR_CRITICAL("WRONG acquisition start trigger:0x%04X.\n",
1435 trigger->iAcqStartTrigType);
1436 err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
1437 goto VERIFY_ERROR;
1438 break;
1439 }
1440
1441 switch (trigger->iScanStartTrigType) {
1442 case ME_TRIG_TYPE_TIMER:
1443 --scan_ticks;
1444 outl(scan_ticks, instance->scan_timer_low_reg);
1445 PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%llX\n",
1446 instance->reg_base,
1447 instance->scan_timer_low_reg - instance->reg_base,
1448 scan_ticks & 0xFFFFFFFF);
1449 outl((scan_ticks >> 32), instance->scan_timer_high_reg);
1450 PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%llX\n",
1451 instance->reg_base,
1452 instance->scan_timer_high_reg - instance->reg_base,
1453 (scan_ticks >> 32) & 0xFFFFFFFF);
1454
1455 if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) {
1456 ctrl |= ME4600_AI_CTRL_BIT_MODE_0;
1457 } else {
1458 ctrl |= ME4600_AI_CTRL_BIT_MODE_1;
1459 }
1460 break;
1461
1462 case ME_TRIG_TYPE_EXT_DIGITAL:
1463 case ME_TRIG_TYPE_EXT_ANALOG:
1464 outl(0, instance->scan_timer_low_reg);
1465 PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
1466 instance->reg_base,
1467 instance->scan_timer_low_reg - instance->reg_base,
1468 0);
1469 outl(0, instance->scan_timer_high_reg);
1470 PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
1471 instance->reg_base,
1472 instance->scan_timer_high_reg - instance->reg_base,
1473 0);
1474 ctrl |= ME4600_AI_CTRL_BIT_MODE_2;
1475 break;
1476
1477 case ME_TRIG_TYPE_FOLLOW:
1478 outl(0, instance->scan_timer_low_reg);
1479 PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
1480 instance->reg_base,
1481 instance->scan_timer_low_reg - instance->reg_base,
1482 0);
1483 outl(0, instance->scan_timer_high_reg);
1484 PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
1485 instance->reg_base,
1486 instance->scan_timer_high_reg - instance->reg_base,
1487 0);
1488
1489 if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) {
1490 ctrl |= ME4600_AI_CTRL_BIT_MODE_0;
1491 } else {
1492 ctrl |= ME4600_AI_CTRL_BIT_MODE_1;
1493 }
1494 break;
1495
1496 default:
1497 PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n");
1498 PERROR_CRITICAL("WRONG scan start trigger:0x%04X.\n",
1499 trigger->iScanStartTrigType);
1500 err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
1501 goto VERIFY_ERROR;
1502 break;
1503 }
1504
1505 switch (trigger->iConvStartTrigType) {
1506
1507 case ME_TRIG_TYPE_TIMER:
1508 --conv_ticks;
1509 outl(conv_ticks, instance->chan_timer_reg);
1510 PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%llX\n",
1511 instance->reg_base,
1512 instance->chan_timer_reg - instance->reg_base,
1513 conv_ticks);
1514 break;
1515
1516 case ME_TRIG_TYPE_EXT_DIGITAL:
1517 case ME_TRIG_TYPE_EXT_ANALOG:
1518 outl(0, instance->chan_timer_reg);
1519 PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
1520 instance->reg_base,
1521 instance->chan_timer_reg - instance->reg_base, 0);
1522 ctrl |= ME4600_AI_CTRL_BIT_MODE_0 | ME4600_AI_CTRL_BIT_MODE_1;
1523 break;
1524
1525 default:
1526 PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n");
1527 PERROR_CRITICAL("WRONG conv start trigger:0x%04X.\n",
1528 trigger->iConvStartTrigType);
1529 err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
1530 goto VERIFY_ERROR;
1531
1532 break;
1533 }
1534
1535 //Sample & Hold feature
1536 if (flags & ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD) {
1537 if (instance->sh) {
1538 ctrl |= ME4600_AI_CTRL_BIT_SAMPLE_HOLD;
1539 } else {
1540 PERROR_CRITICAL("UNCHECK S&H feature!\n");
1541 err = ME_ERRNO_INVALID_FLAGS;
1542 goto VERIFY_ERROR;
1543 }
1544 }
1545 //Enable IRQs sources but leave latches blocked.
1546 ctrl |= (ME4600_AI_CTRL_BIT_HF_IRQ | ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_LE_IRQ); //The last IRQ source (ME4600_AI_CTRL_BIT_LE_IRQ) is unused!
1547
1548 //Everything is good. Finalize
1549 spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
1550 tmp = inl(instance->ctrl_reg);
1551
1552 //Preserve EXT IRQ and OFFSET settings. Clean other bits.
1553 tmp &=
1554 (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET |
1555 ME4600_AI_CTRL_BIT_FULLSCALE | ME4600_AI_CTRL_BIT_OFFSET);
1556
1557 // write the control word
1558 outl(ctrl | tmp, instance->ctrl_reg);
1559 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1560 instance->ctrl_reg - instance->reg_base, ctrl | tmp);
1561 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
1562
1563 //Set the global parameters end exit.
1564 instance->chan_list_len = count;
1565 instance->fifo_irq_threshold = fifo_irq_threshold;
1566
1567 if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) {
1568 data_required =
1569 (unsigned long long)trigger->iAcqStopCount *
1570 (unsigned long long)count;
1571 if (data_required > UINT_MAX)
1572 data_required = UINT_MAX;
1573 instance->data_required = (unsigned int)data_required;
1574 } else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT)
1575 instance->data_required =
1576 (unsigned long long)trigger->iScanStopCount;
1577 else
1578 instance->data_required = 0;
1579
1580 // Mark subdevice as configured to work in stream mode.
1581 instance->status = ai_status_stream_configured;
1582
1583 // Deinit single config. Set all entries to NOT_CONFIGURED.
1584 for (i = 0; i < instance->channels; i++) {
1585 instance->single_config[i].status =
1586 ME_SINGLE_CHANNEL_NOT_CONFIGURED;
1587 }
1588
1589 VERIFY_ERROR: // Error in code. Wrong setting check. This should never ever happend!
1590 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
1591 ERROR: // Error in settings.
1592 ME_SUBDEVICE_EXIT;
1593
1594 return err;
1595}
1596
1597static int me4600_ai_io_stream_new_values(me_subdevice_t * subdevice,
1598 struct file *filep,
1599 int time_out, int *count, int flags)
1600{
1601 me4600_ai_subdevice_t *instance;
1602 int err = ME_ERRNO_SUCCESS;
1603 unsigned long t;
1604 unsigned long j;
1605 int volatile head;
1606
1607 PDEBUG("executed. idx=0\n");
1608
1609 if (flags) {
1610 PERROR("Invalid flag specified.\n");
1611 return ME_ERRNO_INVALID_FLAGS;
1612 }
1613
1614 if (time_out < 0) {
1615 PERROR("Invalid time_out specified.\n");
1616 return ME_ERRNO_INVALID_TIMEOUT;
1617 }
1618
1619 if (time_out) {
1620 t = (time_out * HZ) / 1000;
1621
1622 if (t == 0)
1623 t = 1;
1624 } else { // Max time.
1625 t = LONG_MAX;
1626 }
1627
1628 instance = (me4600_ai_subdevice_t *) subdevice;
1629
1630 ME_SUBDEVICE_ENTER;
1631
1632 j = jiffies;
1633
1634 while (1) {
1635 // Only runing device can generate break.
1636 head = instance->circ_buf.head;
1637 wait_event_interruptible_timeout(instance->wait_queue,
1638 ((head !=
1639 instance->circ_buf.head)
1640 ||
1641 ((instance->status <=
1642 ai_status_stream_run_wait)
1643 && (instance->status >=
1644 ai_status_stream_end_wait))),
1645 t);
1646
1647 if (head != instance->circ_buf.head) { // New data in buffer.
1648 break;
1649 } else if (instance->status == ai_status_stream_end) { // End of work.
1650 break;
1651 } else if (instance->status == ai_status_stream_fifo_error) {
1652 err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
1653 break;
1654 } else if (instance->status == ai_status_stream_buffer_error) {
1655 err = ME_ERRNO_RING_BUFFER_OVERFLOW;
1656 break;
1657 } else if (instance->status == ai_status_stream_error) {
1658 err = ME_ERRNO_INTERNAL;
1659 break;
1660 } else if ((jiffies - j) >= t) {
1661 PERROR("Wait on values timed out.\n");
1662 err = ME_ERRNO_TIMEOUT;
1663 break;
1664 } else if (signal_pending(current)) {
1665 PERROR("Wait on values interrupted from signal.\n");
1666 err = ME_ERRNO_SIGNAL;
1667 break;
1668 }
1669 // Correct timeout.
1670 t -= jiffies - j;
1671 }
1672
1673 *count = me_circ_buf_values(&instance->circ_buf);
1674
1675 ME_SUBDEVICE_EXIT;
1676
1677 return err;
1678}
1679
1680static int inline me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
1681 instance, int *values,
1682 const int count,
1683 const int flags)
1684{
1685 int n;
1686 int i;
1687 uint32_t value;
1688
1689 ///Checking how many datas can be copied.
1690 n = me_circ_buf_values(&instance->circ_buf);
1691 if (n <= 0)
1692 return 0;
1693
1694 if (n > count)
1695 n = count;
1696
1697 if (flags & ME_IO_STREAM_READ_FRAMES) {
1698 if (n < instance->chan_list_len) //Not enough data!
1699 return 0;
1700 n -= n % instance->chan_list_len;
1701 }
1702
1703 for (i = 0; i < n; i++) {
1704 value = *(instance->circ_buf.buf + instance->circ_buf.tail);
1705 if (put_user(value, values + i)) {
1706 PERROR("Cannot copy new values to user.\n");
1707 return -ME_ERRNO_INTERNAL;
1708 }
1709 instance->circ_buf.tail++;
1710 instance->circ_buf.tail &= instance->circ_buf.mask;
1711 }
1712 return n;
1713}
1714
1715static int me4600_ai_io_stream_read(me_subdevice_t * subdevice,
1716 struct file *filep,
1717 int read_mode,
1718 int *values, int *count, int flags)
1719{
1720 me4600_ai_subdevice_t *instance;
1721 int err = ME_ERRNO_SUCCESS;
1722 int ret;
1723
1724 int c = *count;
1725 int min = c;
1726
1727 PDEBUG("executed. idx=0\n");
1728
1729 if (flags & ~ME_IO_STREAM_READ_FRAMES) {
1730 PERROR("Invalid flag specified.\n");
1731 return ME_ERRNO_INVALID_FLAGS;
1732 }
1733
1734 if (!values || !count) {
1735 PERROR("Request has invalid pointer.\n");
1736 return ME_ERRNO_INVALID_POINTER;
1737 }
1738
1739 if (c < 0) {
1740 PERROR("Request has invalid value's counter.\n");
1741 return ME_ERRNO_INVALID_VALUE_COUNT;
1742 }
1743
1744 if ((read_mode != ME_READ_MODE_BLOCKING)
1745 && (read_mode != ME_READ_MODE_NONBLOCKING)) {
1746 PERROR("Invalid read mode specified.\n");
1747 return ME_ERRNO_INVALID_READ_MODE;
1748 }
1749
1750 if (c == 0) { //You get what you want! Nothing more or less.
1751 return ME_ERRNO_SUCCESS;
1752 }
1753
1754 instance = (me4600_ai_subdevice_t *) subdevice;
1755 ME_SUBDEVICE_ENTER;
1756
1757 //Check if subdevice is configured.
1758 if (instance->chan_list_len <= 0) {
1759 PERROR("Subdevice wasn't configured.\n");
1760 ME_SUBDEVICE_EXIT;
1761 return ME_ERRNO_PREVIOUS_CONFIG;
1762 }
1763
1764 if (flags & ME_IO_STREAM_READ_FRAMES) {
1765 if (c < instance->chan_list_len) { //Not enough data requested.
1766 PERROR
1767 ("When using FRAME_READ mode minimal size is defined by channel list.\n");
1768 ME_SUBDEVICE_EXIT;
1769 return ME_ERRNO_INVALID_VALUE_COUNT;
1770 }
1771 }
1772
1773 if (c > (ME4600_AI_CIRC_BUF_COUNT - instance->chan_list_len)) { // To return acceptable amount of data when user pass too big value.
1774 min = ME4600_AI_CIRC_BUF_COUNT - instance->chan_list_len;
1775 }
1776
1777 if (flags & ME_IO_STREAM_READ_FRAMES) {
1778 //Wait for whole list.
1779 if (read_mode == ME_READ_MODE_BLOCKING) {
1780 min = c - (c % instance->chan_list_len);
1781 }
1782
1783 if (read_mode == ME_READ_MODE_NONBLOCKING) {
1784 min = instance->chan_list_len;
1785 }
1786 }
1787
1788 if ((inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM)) { //Working
1789 //If blocking mode -> wait for data.
1790 if ((me_circ_buf_values(&instance->circ_buf) < min)
1791 && (read_mode == ME_READ_MODE_BLOCKING)) {
1792 wait_event_interruptible(instance->wait_queue,
1793 ((me_circ_buf_values
1794 (&instance->circ_buf) >= min)
1795 || !(inl(instance->status_reg)
1796 &
1797 ME4600_AI_STATUS_BIT_FSM)));
1798
1799 if (signal_pending(current)) {
1800 PERROR
1801 ("Wait on values interrupted from signal.\n");
1802 err = ME_ERRNO_SIGNAL;
1803 }
1804 }
1805 }
1806
1807 ret = me4600_ai_io_stream_read_get_value(instance, values, c, flags);
1808 if (ret < 0) {
1809 err = -ret;
1810 *count = 0;
1811 } else if (ret == 0) {
1812 *count = 0;
1813 if (instance->status == ai_status_stream_fifo_error) {
1814 err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
1815 instance->status = ai_status_stream_end;
1816 } else if (instance->status == ai_status_stream_buffer_error) {
1817 err = ME_ERRNO_RING_BUFFER_OVERFLOW;
1818 instance->status = ai_status_stream_end;
1819 } else if (instance->status == ai_status_stream_end) {
1820 err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
1821 } else if (instance->status == ai_status_stream_error) {
1822 err = ME_ERRNO_INTERNAL;
1823 } else if (instance->status == ai_status_none) {
1824 PDEBUG("Stream canceled.\n");
1825 err = ME_ERRNO_INTERNAL;
1826 }
1827 } else {
1828 *count = ret;
1829 }
1830
1831 ME_SUBDEVICE_EXIT;
1832
1833 return err;
1834}
1835
1836/** @brief Stop aqusation. Preserve FIFOs.
1837*
1838* @param instance The subdevice instance (pointer).
1839*/
1840
1841static int ai_stop_immediately(me4600_ai_subdevice_t * instance)
1842{
1843 unsigned long cpu_flags = 0;
1844 volatile uint32_t ctrl;
1845 const int timeout = HZ / 10; //100ms
1846 int i;
1847
1848 for (i = 0; i <= timeout; i++) {
1849 spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
1850 ctrl = inl(instance->ctrl_reg);
1851 ctrl &= ~ME4600_AI_CTRL_BIT_STOP;
1852 ctrl |=
1853 (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP |
1854 ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
1855 ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
1856 outl(ctrl, instance->ctrl_reg);
1857 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
1858 instance->reg_base,
1859 instance->ctrl_reg - instance->reg_base, ctrl);
1860 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
1861
1862 if (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM)) { // Exit.
1863 break;
1864 }
1865
1866 PINFO("Wait for stop: %d\n", i + 1);
1867 //Still working!
1868 set_current_state(TASK_INTERRUPTIBLE);
1869 schedule_timeout(1);
1870 }
1871
1872 if (i > timeout) {
1873 PERROR_CRITICAL("FSM IS BUSY!\n");
1874 return ME_ERRNO_INTERNAL;
1875 }
1876
1877 return ME_ERRNO_SUCCESS;
1878}
1879
1880static int me4600_ai_io_stream_start(me_subdevice_t * subdevice,
1881 struct file *filep,
1882 int start_mode, int time_out, int flags)
1883{
1884 me4600_ai_subdevice_t *instance;
1885 int err = ME_ERRNO_SUCCESS;
1886 unsigned long cpu_flags = 0;
1887 unsigned long ref;
1888 unsigned long delay = 0;
1889
1890 volatile uint32_t tmp;
1891
1892 PDEBUG("executed. idx=0\n");
1893
1894 instance = (me4600_ai_subdevice_t *) subdevice;
1895
1896 if (flags) {
1897 PERROR("Invalid flag specified.\n");
1898 return ME_ERRNO_INVALID_FLAGS;
1899 }
1900
1901 if ((start_mode != ME_START_MODE_BLOCKING)
1902 && (start_mode != ME_START_MODE_NONBLOCKING)) {
1903 PERROR("Invalid start mode specified.\n");
1904 return ME_ERRNO_INVALID_START_MODE;
1905 }
1906
1907 if (time_out < 0) {
1908 PERROR("Invalid timeout specified.\n");
1909 return ME_ERRNO_INVALID_TIMEOUT;
1910 }
1911
1912 if (time_out) {
1913 delay = (time_out * HZ) / 1000;
1914
1915 if (delay == 0)
1916 delay = 1;
1917 }
1918
1919 ME_SUBDEVICE_ENTER
1920 spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
1921
1922 tmp = inl(instance->ctrl_reg);
1923
1924 if ((tmp & ME4600_AI_STATUS_BIT_FSM)) {
1925 PERROR("Conversion is already running.\n");
1926 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
1927 err = ME_ERRNO_SUBDEVICE_BUSY;
1928 goto ERROR;
1929 }
1930
1931 if (instance->chan_list_len == 0) { //Not configured!
1932 PERROR("Subdevice is not configured to work in stream mode!\n");
1933 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
1934 err = ME_ERRNO_PREVIOUS_CONFIG;
1935 goto ERROR;
1936 }
1937
1938 if (!(tmp & (ME4600_AI_CTRL_BIT_MODE_0 | ME4600_AI_CTRL_BIT_MODE_1 | ME4600_AI_CTRL_BIT_MODE_2))) { //Mode 0 = single work => no stream config
1939 PERROR("Subdevice is configured to work in single mode.\n");
1940 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
1941 err = ME_ERRNO_PREVIOUS_CONFIG;
1942 goto ERROR;
1943 }
1944 //Reset stop bits.
1945 tmp |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_STOP;
1946 outl(tmp, instance->ctrl_reg);
1947 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1948 instance->ctrl_reg - instance->reg_base, tmp);
1949
1950 //Start datas' FIFO.
1951 tmp |= ME4600_AI_CTRL_BIT_DATA_FIFO;
1952 //Free stop bits.
1953 tmp &= ~(ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_STOP);
1954 outl(tmp, instance->ctrl_reg);
1955 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1956 instance->ctrl_reg - instance->reg_base, tmp);
1957 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
1958
1959 //Cancel control task
1960 PDEBUG("Cancel control task.\n");
1961 instance->ai_control_task_flag = 0;
1962 cancel_delayed_work(&instance->ai_control_task);
1963
1964 //Set the starting values.
1965 instance->ISM.global_read = 0;
1966 instance->ISM.read = 0;
1967 //Clear circular buffer
1968 instance->circ_buf.head = 0;
1969 instance->circ_buf.tail = 0;
1970
1971 //Set everything.
1972 ai_data_acquisition_logic(instance);
1973
1974 //Set status to 'wait for start'
1975 instance->status = ai_status_stream_run_wait;
1976
1977 // Set control task's timeout
1978 instance->timeout.delay = delay;
1979 instance->timeout.start_time = jiffies;
1980
1981 //Lets go! Start work
1982 inl(instance->start_reg);
1983 PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
1984 instance->start_reg - instance->reg_base);
1985
1986 // Schedule control task
1987 instance->ai_control_task_flag = 1;
1988 queue_delayed_work(instance->me4600_workqueue,
1989 &instance->ai_control_task, 1);
1990
1991 PDEVELOP("Delay:%ld\n", delay);
1992
1993 if (start_mode == ME_START_MODE_BLOCKING) { //Wait for start.
1994 ref = jiffies;
1995 //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
1996 wait_event_interruptible_timeout(instance->wait_queue,
1997 (instance->status !=
1998 ai_status_stream_run_wait),
1999 (delay) ? delay +
2000 1 : LONG_MAX);
2001
2002 if ((instance->status != ai_status_stream_run)
2003 && (instance->status != ai_status_stream_end)) {
2004 PDEBUG("Starting stream canceled. %d\n",
2005 instance->status);
2006 err = ME_ERRNO_CANCELLED;
2007 }
2008
2009 if (signal_pending(current)) {
2010 PERROR("Wait on start of state machine interrupted.\n");
2011 instance->status = ai_status_none;
2012 ai_stop_isr(instance);
2013 err = ME_ERRNO_SIGNAL;
2014 } else if ((delay) && ((jiffies - ref) > delay)) {
2015 if (instance->status != ai_status_stream_run) {
2016 if (instance->status == ai_status_stream_end) {
2017 PDEBUG("Timeout reached.\n");
2018 } else if ((jiffies - ref) > delay + 1) {
2019 PERROR
2020 ("Timeout reached. Not handled by control task!\n");
2021 ai_stop_isr(instance);
2022 instance->status =
2023 ai_status_stream_error;
2024 } else {
2025 PERROR
2026 ("Timeout reached. Signal come but status is strange: %d\n",
2027 instance->status);
2028 ai_stop_isr(instance);
2029 instance->status =
2030 ai_status_stream_error;
2031 }
2032
2033 instance->ai_control_task_flag = 0;
2034 cancel_delayed_work(&instance->ai_control_task);
2035 err = ME_ERRNO_TIMEOUT;
2036 }
2037 }
2038 }
2039#ifdef MEDEBUG_INFO
2040 tmp = inl(instance->ctrl_reg);
2041 PDEBUG_REG("ctrl_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
2042 instance->ctrl_reg - instance->reg_base, tmp);
2043
2044 PINFO("STATUS_BIT_FSM=%s.\n",
2045 (tmp & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off");
2046 PINFO("CTRL_BIT_HF_IRQ=%s.\n",
2047 (tmp & ME4600_AI_CTRL_BIT_HF_IRQ) ? "enable" : "disable");
2048 PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n",
2049 (tmp & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" : "work");
2050 PINFO("CTRL_BIT_SC_IRQ=%s.\n",
2051 (tmp & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable");
2052 PINFO("CTRL_BIT_SC_RELOAD=%s.\n",
2053 (tmp & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off");
2054 PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n",
2055 (tmp & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" : "work");
2056#endif
2057
2058 ERROR:
2059 ME_SUBDEVICE_EXIT;
2060
2061 return err;
2062}
2063
2064static int me4600_ai_io_stream_status(me_subdevice_t * subdevice,
2065 struct file *filep,
2066 int wait,
2067 int *status, int *values, int flags)
2068{
2069 me4600_ai_subdevice_t *instance;
2070 int err = ME_ERRNO_SUCCESS;
2071
2072 PDEBUG("executed. idx=0\n");
2073
2074 instance = (me4600_ai_subdevice_t *) subdevice;
2075
2076 if (flags) {
2077 PERROR("Invalid flag specified.\n");
2078 return ME_ERRNO_INVALID_FLAGS;
2079 }
2080
2081 ME_SUBDEVICE_ENTER;
2082
2083 switch (instance->status) {
2084 case ai_status_single_configured:
2085 case ai_status_stream_configured:
2086 case ai_status_stream_end:
2087 case ai_status_stream_fifo_error:
2088 case ai_status_stream_buffer_error:
2089 case ai_status_stream_error:
2090 *status = ME_STATUS_IDLE;
2091 break;
2092
2093 case ai_status_stream_run_wait:
2094 case ai_status_stream_run:
2095 case ai_status_stream_end_wait:
2096 *status = ME_STATUS_BUSY;
2097 break;
2098
2099 case ai_status_none:
2100 default:
2101 *status =
2102 (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) ?
2103 ME_STATUS_BUSY : ME_STATUS_IDLE;
2104 break;
2105 }
2106
2107 if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) {
2108 // Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
2109 wait_event_interruptible_timeout(instance->wait_queue,
2110 ((instance->status !=
2111 ai_status_stream_run_wait)
2112 && (instance->status !=
2113 ai_status_stream_run)
2114 && (instance->status !=
2115 ai_status_stream_end_wait)),
2116 LONG_MAX);
2117
2118 if (instance->status != ai_status_stream_end) {
2119 PDEBUG("Wait for IDLE canceled. %d\n",
2120 instance->status);
2121 err = ME_ERRNO_CANCELLED;
2122 }
2123
2124 if (signal_pending(current)) {
2125 PERROR("Wait for IDLE interrupted.\n");
2126 instance->status = ai_status_none;
2127 ai_stop_isr(instance);
2128 err = ME_ERRNO_SIGNAL;
2129 }
2130
2131 *status = ME_STATUS_IDLE;
2132 }
2133
2134 *values = me_circ_buf_values(&instance->circ_buf);
2135 PDEBUG("me_circ_buf_values(&instance->circ_buf)=%d.\n", *values);
2136
2137 ME_SUBDEVICE_EXIT;
2138
2139 return err;
2140}
2141
2142static int me4600_ai_io_stream_stop(me_subdevice_t * subdevice,
2143 struct file *filep,
2144 int stop_mode, int flags)
2145{
2146/**
2147 @note Stop is implemented only in blocking mode.
2148 @note Function return when state machine is stoped.
2149*/
2150 me4600_ai_subdevice_t *instance;
2151 unsigned long cpu_flags;
2152 uint32_t ctrl;
2153 int ret;
2154
2155 PDEBUG("executed. idx=0\n");
2156
2157 if (flags) {
2158 PERROR("Invalid flag specified.\n");
2159 return ME_ERRNO_INVALID_FLAGS;
2160 }
2161
2162 if ((stop_mode != ME_STOP_MODE_IMMEDIATE)
2163 && (stop_mode != ME_STOP_MODE_LAST_VALUE)) {
2164 PERROR("Invalid stop mode specified.\n");
2165 return ME_ERRNO_INVALID_STOP_MODE;
2166 }
2167
2168 instance = (me4600_ai_subdevice_t *) subdevice;
2169
2170 ME_SUBDEVICE_ENTER;
2171
2172 // Mark as stopping. => Software stop.
2173 instance->status = ai_status_stream_end_wait;
2174
2175 if (stop_mode == ME_STOP_MODE_IMMEDIATE) {
2176 ret = ai_stop_immediately(instance);
2177
2178 if (ret) {
2179 PERROR("FSM is still busy.\n");
2180 ME_SUBDEVICE_EXIT;
2181 return ME_ERRNO_SUBDEVICE_BUSY;
2182 }
2183 instance->ai_control_task_flag = 0;
2184
2185 } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
2186 // Set stop bit in registry.
2187 spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
2188 ctrl = inl(instance->ctrl_reg);
2189 ctrl |= ME4600_AI_CTRL_BIT_STOP;
2190 outl(ctrl, instance->ctrl_reg);
2191 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2192 instance->reg_base,
2193 instance->ctrl_reg - instance->reg_base, ctrl);
2194 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
2195
2196 // Only runing process will interrupt this call. Events are signaled when status change.
2197 wait_event_interruptible_timeout(instance->wait_queue,
2198 (instance->status !=
2199 ai_status_stream_end_wait),
2200 LONG_MAX);
2201
2202 if (instance->status != ai_status_stream_end) {
2203 PDEBUG("Stopping stream canceled.\n");
2204 ret = ME_ERRNO_CANCELLED;
2205 }
2206
2207 if (signal_pending(current)) {
2208 PERROR("Stopping stream interrupted.\n");
2209 instance->status = ai_status_none;
2210 ret = ME_ERRNO_SIGNAL;
2211 }
2212 // End of work.
2213 ai_stop_immediately(instance);
2214
2215 }
2216
2217 ret = ai_read_data_pooling(instance);
2218 if (ret > 0) { // Everything fine. More datas put to software buffer.
2219 instance->status = ai_status_stream_end;
2220 ret = ME_ERRNO_SUCCESS;
2221 // Signal that we put last data to software buffer.
2222 wake_up_interruptible_all(&instance->wait_queue);
2223 } else if (ret == 0) { // Everything fine. No more datas in FIFO.
2224 instance->status = ai_status_stream_end;
2225 ret = ME_ERRNO_SUCCESS;
2226 } else if (ret == -ME_ERRNO_RING_BUFFER_OVERFLOW) { // Stop is unsuccessful, buffer is overflow.
2227 instance->status = ai_status_stream_buffer_error;
2228 ret = ME_ERRNO_SUCCESS;
2229 } else { // Stop is unsuccessful
2230 instance->status = ai_status_stream_end;
2231 ret = -ret;
2232 }
2233
2234 ME_SUBDEVICE_EXIT;
2235
2236 return ret;
2237}
2238
2239static int me4600_ai_query_range_by_min_max(me_subdevice_t * subdevice,
2240 int unit,
2241 int *min,
2242 int *max, int *maxdata, int *range)
2243{
2244 me4600_ai_subdevice_t *instance;
2245 int i;
2246 int r = -1;
2247 int diff = 21E6;
2248
2249 PDEBUG("executed. idx=0\n");
2250
2251 instance = (me4600_ai_subdevice_t *) subdevice;
2252
2253 if ((*max - *min) < 0) {
2254 PERROR("Invalid minimum and maximum values specified.\n");
2255 return ME_ERRNO_INVALID_MIN_MAX;
2256 }
2257
2258 if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
2259 for (i = 0; i < instance->ranges_len; i++) {
2260 if ((instance->ranges[i].min <= *min)
2261 && ((instance->ranges[i].max + 1000) >= *max)) {
2262 if ((instance->ranges[i].max -
2263 instance->ranges[i].min) - (*max - *min) <
2264 diff) {
2265 r = i;
2266 diff =
2267 (instance->ranges[i].max -
2268 instance->ranges[i].min) - (*max -
2269 *min);
2270 }
2271 }
2272 }
2273
2274 if (r < 0) {
2275 PERROR("No matching range found.\n");
2276 return ME_ERRNO_NO_RANGE;
2277 } else {
2278 *min = instance->ranges[r].min;
2279 *max = instance->ranges[r].max;
2280 *maxdata = ME4600_AI_MAX_DATA;
2281 *range = r;
2282 }
2283 } else {
2284 PERROR("Invalid physical unit specified.\n");
2285 return ME_ERRNO_INVALID_UNIT;
2286 }
2287
2288 return ME_ERRNO_SUCCESS;
2289}
2290
2291static int me4600_ai_query_number_ranges(me_subdevice_t * subdevice,
2292 int unit, int *count)
2293{
2294 me4600_ai_subdevice_t *instance;
2295
2296 PDEBUG("executed. idx=0\n");
2297
2298 instance = (me4600_ai_subdevice_t *) subdevice;
2299
2300 if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
2301 *count = instance->ranges_len;
2302 } else {
2303 *count = 0;
2304 }
2305
2306 return ME_ERRNO_SUCCESS;
2307}
2308
2309static int me4600_ai_query_range_info(me_subdevice_t * subdevice,
2310 int range,
2311 int *unit,
2312 int *min, int *max, int *maxdata)
2313{
2314 me4600_ai_subdevice_t *instance;
2315
2316 PDEBUG("executed. idx=0\n");
2317
2318 instance = (me4600_ai_subdevice_t *) subdevice;
2319
2320 if ((range < instance->ranges_len) && (range >= 0)) {
2321 *unit = ME_UNIT_VOLT;
2322 *min = instance->ranges[range].min;
2323 *max = instance->ranges[range].max;
2324 *maxdata = ME4600_AI_MAX_DATA;
2325 } else {
2326 PERROR("Invalid range number specified.\n");
2327 return ME_ERRNO_INVALID_RANGE;
2328 }
2329
2330 return ME_ERRNO_SUCCESS;
2331}
2332
2333static int me4600_ai_query_timer(me_subdevice_t * subdevice,
2334 int timer,
2335 int *base_frequency,
2336 long long *min_ticks, long long *max_ticks)
2337{
2338 me4600_ai_subdevice_t *instance;
2339
2340 PDEBUG("executed. idx=0\n");
2341
2342 instance = (me4600_ai_subdevice_t *) subdevice;
2343
2344 switch (timer) {
2345
2346 case ME_TIMER_ACQ_START:
2347 *base_frequency = ME4600_AI_BASE_FREQUENCY;
2348 *min_ticks = ME4600_AI_MIN_ACQ_TICKS;
2349 *max_ticks = ME4600_AI_MAX_ACQ_TICKS;
2350 break;
2351
2352 case ME_TIMER_SCAN_START:
2353 *base_frequency = ME4600_AI_BASE_FREQUENCY;
2354 *min_ticks = ME4600_AI_MIN_SCAN_TICKS;
2355 *max_ticks = ME4600_AI_MAX_SCAN_TICKS;
2356 break;
2357
2358 case ME_TIMER_CONV_START:
2359 *base_frequency = ME4600_AI_BASE_FREQUENCY;
2360 *min_ticks = ME4600_AI_MIN_CHAN_TICKS;
2361 *max_ticks = ME4600_AI_MAX_CHAN_TICKS;
2362 break;
2363
2364 default:
2365 PERROR("Invalid timer specified.(0x%04x)\n", timer);
2366
2367 return ME_ERRNO_INVALID_TIMER;
2368 }
2369
2370 return ME_ERRNO_SUCCESS;
2371}
2372
2373static int me4600_ai_query_number_channels(me_subdevice_t * subdevice,
2374 int *number)
2375{
2376 me4600_ai_subdevice_t *instance;
2377
2378 PDEBUG("executed. idx=0\n");
2379
2380 instance = (me4600_ai_subdevice_t *) subdevice;
2381 *number = instance->channels;
2382
2383 return ME_ERRNO_SUCCESS;
2384}
2385
2386static int me4600_ai_query_subdevice_type(me_subdevice_t * subdevice,
2387 int *type, int *subtype)
2388{
2389 PDEBUG("executed. idx=0\n");
2390
2391 *type = ME_TYPE_AI;
2392 *subtype = ME_SUBTYPE_STREAMING;
2393
2394 return ME_ERRNO_SUCCESS;
2395}
2396
2397static int me4600_ai_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
2398{
2399 PDEBUG("executed. idx=0\n");
2400
2401 *caps =
2402 ME_CAPS_AI_TRIG_SYNCHRONOUS | ME_CAPS_AI_FIFO |
2403 ME_CAPS_AI_FIFO_THRESHOLD;
2404
2405 return ME_ERRNO_SUCCESS;
2406}
2407
2408static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
2409 int cap, int *args, int count)
2410{
2411 me4600_ai_subdevice_t *instance;
2412 int err = ME_ERRNO_SUCCESS;
2413
2414 instance = (me4600_ai_subdevice_t *) subdevice;
2415
2416 PDEBUG("executed. idx=0\n");
2417
2418 if (count != 1) {
2419 PERROR("Invalid capability argument count.\n");
2420 return ME_ERRNO_INVALID_CAP_ARG_COUNT;
2421 }
2422
2423 switch (cap) {
2424 case ME_CAP_AI_FIFO_SIZE:
2425 args[0] = ME4600_AI_FIFO_COUNT;
2426 break;
2427
2428 case ME_CAP_AI_BUFFER_SIZE:
2429 args[0] =
2430 (instance->circ_buf.buf) ? ME4600_AI_CIRC_BUF_COUNT : 0;
2431 break;
2432
2433 default:
2434 PERROR("Invalid capability.\n");
2435 err = ME_ERRNO_INVALID_CAP;
2436 args[0] = 0;
2437 }
2438
2439 return err;
2440}
2441
2442void ai_limited_isr(me4600_ai_subdevice_t * instance, const uint32_t irq_status,
2443 const uint32_t ctrl_status)
2444{
2445 int to_read;
2446
2447 if (!instance->fifo_irq_threshold) { //No threshold provided. SC ends work. HF need reseting.
2448 if (irq_status & ME4600_IRQ_STATUS_BIT_SC) {
2449 if (ai_read_data(instance, instance->ISM.next) != instance->ISM.next) { //ERROR!
2450 PERROR
2451 ("Limited amounts aqusition with TH=0: Circular buffer full!\n");
2452 instance->status =
2453 ai_status_stream_buffer_error;
2454 } else {
2455 instance->status = ai_status_stream_end;
2456 }
2457 //End of work.
2458 ai_stop_isr(instance);
2459 } else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) {
2460 instance->ISM.global_read += ME4600_AI_FIFO_HALF;
2461
2462 if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) { //ERROR!
2463 PERROR
2464 ("Limited amounts aqusition with TH = 0: Circular buffer full!\n");
2465 //End of work.
2466 ai_stop_isr(instance);
2467 instance->status =
2468 ai_status_stream_buffer_error;
2469 } else {
2470 //Continue.
2471 ai_limited_ISM(instance, irq_status);
2472 }
2473 }
2474 //Signal user.
2475 wake_up_interruptible_all(&instance->wait_queue);
2476 } else //if(instance->fifo_irq_threshold)
2477 {
2478 if (irq_status & ME4600_IRQ_STATUS_BIT_SC) {
2479 instance->ISM.read = 0;
2480 if ((instance->fifo_irq_threshold < ME4600_AI_FIFO_HALF)
2481 && (!(ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA)))
2482 {
2483 to_read =
2484 ME4600_AI_FIFO_HALF -
2485 (ME4600_AI_FIFO_HALF %
2486 instance->fifo_irq_threshold);
2487 PDEBUG
2488 ("Limited amounts aqusition with TH != 0: Not fast enough data aqusition! correction=%d\n",
2489 to_read);
2490 } else {
2491 to_read = instance->ISM.next;
2492 }
2493 instance->ISM.global_read += to_read;
2494
2495 ai_reschedule_SC(instance);
2496
2497 if (ai_read_data(instance, to_read) != to_read) { //ERROR!
2498 PERROR
2499 ("Limited amounts aqusition with TH != 0: Circular buffer full!\n");
2500 //End of work.
2501 ai_stop_isr(instance);
2502 instance->status =
2503 ai_status_stream_buffer_error;
2504 } else {
2505 //Continue.
2506 ai_limited_ISM(instance, irq_status);
2507 }
2508
2509 //Signal user.
2510 wake_up_interruptible_all(&instance->wait_queue);
2511 } else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) {
2512 instance->ISM.read += ME4600_AI_FIFO_HALF;
2513 instance->ISM.global_read += ME4600_AI_FIFO_HALF;
2514
2515 if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) { //ERROR!
2516 PERROR
2517 ("Limited amounts aqusition with TH != 0: Circular buffer full!\n");
2518 ai_stop_isr(instance);
2519
2520 instance->status =
2521 ai_status_stream_buffer_error;
2522 //Signal user.
2523 wake_up_interruptible_all(&instance->
2524 wait_queue);
2525 } else {
2526 //Countinue.
2527 ai_limited_ISM(instance, irq_status);
2528 }
2529 }
2530
2531 if (instance->ISM.global_read >= instance->data_required) { //End of work. Next paranoid pice of code: '>=' instead od '==' only to be sure.
2532 ai_stop_isr(instance);
2533 if (instance->status < ai_status_stream_end) {
2534 instance->status = ai_status_stream_end;
2535 }
2536#ifdef MEDEBUG_ERROR
2537 if (instance->ISM.global_read > instance->data_required) { //This is security check case. This should never ever happend!
2538 PERROR
2539 ("Limited amounts aqusition: Read more data than necessary! data_required=%d < read=%d\n",
2540 instance->data_required,
2541 instance->ISM.global_read);
2542 //Signal error (warning??).
2543 instance->status = ai_status_stream_error;
2544 }
2545#endif
2546 }
2547 }
2548}
2549
2550void ai_infinite_isr(me4600_ai_subdevice_t * instance,
2551 const uint32_t irq_status, const uint32_t ctrl_status)
2552{
2553 int to_read;
2554
2555 if (irq_status & ME4600_IRQ_STATUS_BIT_SC) { //next chunck of data -> read fifo
2556 //Set new state in ISM.
2557 if ((instance->fifo_irq_threshold < ME4600_AI_FIFO_HALF) && (!(ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA))) { //There is more data than we ecpected. Propably we aren't fast enough. Read as many as possible.
2558 if (instance->fifo_irq_threshold) {
2559 to_read =
2560 ME4600_AI_FIFO_HALF -
2561 (ME4600_AI_FIFO_HALF %
2562 instance->fifo_irq_threshold);
2563 if (to_read > instance->fifo_irq_threshold) {
2564 PDEBUG
2565 ("Infinite aqusition: Not fast enough data aqusition! TH != 0: correction=%d\n",
2566 to_read);
2567 }
2568 } else { //No threshold specified.
2569 to_read = ME4600_AI_FIFO_HALF;
2570 }
2571 } else {
2572 to_read = instance->ISM.next;
2573 }
2574
2575 instance->ISM.read += to_read;
2576
2577 //Get data
2578 if (ai_read_data(instance, to_read) != to_read) { //ERROR!
2579 PERROR("Infinite aqusition: Circular buffer full!\n");
2580 ai_stop_isr(instance);
2581 instance->status = ai_status_stream_buffer_error;
2582 } else {
2583 ai_infinite_ISM(instance);
2584 instance->ISM.global_read += instance->ISM.read;
2585 instance->ISM.read = 0;
2586 }
2587
2588 //Signal data to user
2589 wake_up_interruptible_all(&instance->wait_queue);
2590 } else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) { //fifo is half full -> read fifo Large blocks only!
2591 instance->ISM.read += ME4600_AI_FIFO_HALF;
2592
2593 if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) { //ERROR!
2594 PERROR("Infinite aqusition: Circular buffer full!\n");
2595 ai_stop_isr(instance);
2596 instance->status = ai_status_stream_buffer_error;
2597
2598 //Signal it.
2599 wake_up_interruptible_all(&instance->wait_queue);
2600 } else {
2601 ai_infinite_ISM(instance);
2602 }
2603 }
2604}
2605
2606#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
2607static irqreturn_t me4600_ai_isr(int irq, void *dev_id)
2608#else
2609static irqreturn_t me4600_ai_isr(int irq, void *dev_id, struct pt_regs *regs)
2610#endif
2611{ /// @note This is time critical function!
2612 uint32_t irq_status;
2613 uint32_t ctrl_status;
2614 me4600_ai_subdevice_t *instance = dev_id;
2615 //int to_read;
2616
2617 PDEBUG("executed. idx=0\n");
2618
2619 if (irq != instance->irq) {
2620 PERROR("Incorrect interrupt num: %d.\n", irq);
2621 return IRQ_NONE;
2622 }
2623
2624 irq_status = inl(instance->irq_status_reg);
2625 if (!
2626 (irq_status &
2627 (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC))) {
2628#ifdef MEDEBUG_INFO
2629 if ((irq_status & (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC | ME4600_IRQ_STATUS_BIT_LE)) == ME4600_IRQ_STATUS_BIT_LE) { //This is security check case. LE is unused. This should never ever happend.
2630 PINFO
2631 ("%ld Shared interrupt. %s(): irq_status_reg=LE_IRQ\n",
2632 jiffies, __FUNCTION__);
2633 } else {
2634 PINFO
2635 ("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n",
2636 jiffies, __FUNCTION__, irq_status);
2637 }
2638#endif
2639 return IRQ_NONE;
2640 }
2641
2642 if (!instance->circ_buf.buf) { //Security check.
2643 PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n");
2644 ai_stop_isr(instance);
2645 return IRQ_HANDLED;
2646 }
2647 //Get the status register.
2648 ctrl_status = inl(instance->status_reg);
2649
2650#ifdef MEDEBUG_INFO
2651 if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF)
2652 PINFO("HF interrupt active\n");
2653 if (irq_status & ME4600_IRQ_STATUS_BIT_SC)
2654 PINFO("SC interrupt active\n");
2655 if (irq_status & ME4600_IRQ_STATUS_BIT_LE)
2656 PINFO("LE interrupt active\n");
2657#endif
2658
2659 //This is safety check!
2660 if ((irq_status & ME4600_IRQ_STATUS_BIT_AI_HF)
2661 && (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA)) {
2662 PDEBUG("HF interrupt active but FIFO under half\n");
2663 //Reset HF interrupt latch.
2664 spin_lock(instance->ctrl_reg_lock);
2665 outl(ctrl_status | ME4600_AI_CTRL_BIT_HF_IRQ_RESET,
2666 instance->ctrl_reg);
2667 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2668 instance->reg_base,
2669 instance->ctrl_reg - instance->reg_base,
2670 ctrl_status);
2671 outl(ctrl_status, instance->ctrl_reg);
2672 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2673 instance->reg_base,
2674 instance->ctrl_reg - instance->reg_base,
2675 ctrl_status);
2676 spin_unlock(instance->ctrl_reg_lock);
2677 return IRQ_HANDLED;
2678 }
2679#ifdef MEDEBUG_INFO
2680 PINFO("STATUS_BIT_FSM=%s.\n",
2681 (ctrl_status & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off");
2682
2683 PINFO("STATUS_BIT_EF_CHANNEL=%s.\n",
2684 (ctrl_status & ME4600_AI_STATUS_BIT_EF_CHANNEL) ? "not empty" :
2685 "empty");
2686 PINFO("STATUS_BIT_HF_CHANNEL=%s.\n",
2687 (ctrl_status & ME4600_AI_STATUS_BIT_HF_CHANNEL) ? " < HF" :
2688 " > HF");
2689 PINFO("STATUS_BIT_FF_CHANNEL=%s.\n",
2690 (ctrl_status & ME4600_AI_STATUS_BIT_FF_CHANNEL) ? "not full" :
2691 "full");
2692
2693 PINFO("STATUS_BIT_EF_DATA=%s.\n",
2694 (ctrl_status & ME4600_AI_STATUS_BIT_EF_DATA) ? "not empty" :
2695 "empty");
2696 PINFO("STATUS_BIT_HF_DATA=%s.\n",
2697 (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA) ? " < HF" : " > HF");
2698 PINFO("STATUS_BIT_FF_DATA=%s.\n",
2699 (ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA) ? "not full" :
2700 "full");
2701
2702 PINFO("CTRL_BIT_HF_IRQ=%s.\n",
2703 (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ) ? "enable" : "disable");
2704 PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n",
2705 (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" :
2706 "work");
2707 PINFO("CTRL_BIT_SC_IRQ=%s.\n",
2708 (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable");
2709 PINFO("CTRL_BIT_SC_RELOAD=%s.\n",
2710 (ctrl_status & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off");
2711 PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n",
2712 (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" :
2713 "work");
2714#endif
2715
2716 //Look for overflow error.
2717 if (!(ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA)) {
2718 //FIFO is full. Read datas and reset all settings.
2719 PERROR("FIFO overflow.\n");
2720 ai_read_data(instance, ME4600_AI_FIFO_COUNT);
2721 ai_stop_isr(instance);
2722
2723 instance->status = ai_status_stream_fifo_error;
2724 //Signal it.
2725 wake_up_interruptible_all(&instance->wait_queue);
2726
2727 return IRQ_HANDLED;
2728 }
2729
2730 if (!instance->data_required) { //This is infinite aqusition.
2731#ifdef MEDEBUG_ERROR
2732 if ((irq_status &
2733 (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC))
2734 ==
2735 (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC)) {
2736 ///In infinite mode only one interrupt source should be reported!
2737 PERROR
2738 ("Error in ISM! Infinite aqusition: HF and SC interrupts active! threshold=%d next=%d ctrl=0x%04X irq_status_reg=0x%04X",
2739 instance->fifo_irq_threshold, instance->ISM.next,
2740 ctrl_status, irq_status);
2741 }
2742#endif
2743
2744 ai_infinite_isr(instance, irq_status, ctrl_status);
2745
2746#ifdef MEDEBUG_INFO
2747 ctrl_status = inl(instance->ctrl_reg);
2748#endif
2749 } else {
2750
2751 ai_limited_isr(instance, irq_status, ctrl_status);
2752 ctrl_status = inl(instance->status_reg);
2753 if (!(ctrl_status & (ME4600_AI_STATUS_BIT_HF_DATA | ME4600_AI_CTRL_BIT_HF_IRQ_RESET))) { //HF active, but we have more than half already => HF will never come
2754 PDEBUG
2755 ("MISSED HF. data_required=%d ISM.read=%d ISM.global=%d ISM.next=%d\n",
2756 instance->data_required, instance->ISM.read,
2757 instance->ISM.global_read, instance->ISM.next);
2758 ai_limited_isr(instance, ME4600_IRQ_STATUS_BIT_AI_HF,
2759 ctrl_status);
2760 }
2761 }
2762
2763#ifdef MEDEBUG_INFO
2764 PINFO("STATUS_BIT_FSM=%s.\n",
2765 (ctrl_status & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off");
2766
2767 PINFO("STATUS_BIT_EF_CHANNEL=%s.\n",
2768 (ctrl_status & ME4600_AI_STATUS_BIT_EF_CHANNEL) ? "not empty" :
2769 "empty");
2770 PINFO("STATUS_BIT_HF_CHANNEL=%s.\n",
2771 (ctrl_status & ME4600_AI_STATUS_BIT_HF_CHANNEL) ? " < HF" :
2772 " > HF");
2773 PINFO("STATUS_BIT_FF_CHANNEL=%s.\n",
2774 (ctrl_status & ME4600_AI_STATUS_BIT_FF_CHANNEL) ? "not full" :
2775 "full");
2776
2777 PINFO("STATUS_BIT_EF_DATA=%s.\n",
2778 (ctrl_status & ME4600_AI_STATUS_BIT_EF_DATA) ? "not empty" :
2779 "empty");
2780 PINFO("STATUS_BIT_HF_DATA=%s.\n",
2781 (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA) ? " < HF" : " > HF");
2782 PINFO("STATUS_BIT_FF_DATA=%s.\n",
2783 (ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA) ? "not full" :
2784 "full");
2785
2786 PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n",
2787 (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" :
2788 "work");
2789 PINFO("CTRL_BIT_SC_IRQ=%s.\n",
2790 (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable");
2791 PINFO("CTRL_BIT_SC_RELOAD=%s.\n",
2792 (ctrl_status & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off");
2793 PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n",
2794 (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" :
2795 "work");
2796 PINFO("%ld END\n", jiffies);
2797#endif
2798
2799 return IRQ_HANDLED;
2800}
2801
2802/** @brief Stop aqusation of data. Reset interrupts' laches. Clear data's FIFO.
2803*
2804* @param instance The subdevice instance (pointer).
2805*/
2806void inline ai_stop_isr(me4600_ai_subdevice_t * instance)
2807{ /// @note This is soft time critical function!
2808 register uint32_t tmp;
2809
2810 spin_lock(instance->ctrl_reg_lock);
2811 //Stop all. Reset interrupt laches. Reset data FIFO.
2812 tmp = inl(instance->ctrl_reg);
2813 tmp |=
2814 (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_HF_IRQ_RESET
2815 | ME4600_AI_CTRL_BIT_LE_IRQ_RESET |
2816 ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
2817 tmp &= ~ME4600_AI_CTRL_BIT_DATA_FIFO;
2818 outl(tmp, instance->ctrl_reg);
2819 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
2820 instance->ctrl_reg - instance->reg_base, tmp);
2821 spin_unlock(instance->ctrl_reg_lock);
2822}
2823
2824/** @brief Copy data from fifo to circular buffer.
2825*
2826* @param instance The subdevice instance (pointer).
2827* @param count The number of requested data.
2828*
2829* @return On success: Number of copied values.
2830* @return On error: -ME_ERRNO_RING_BUFFER_OVERFLOW.
2831*/
2832static int inline ai_read_data(me4600_ai_subdevice_t * instance,
2833 const int count)
2834{ /// @note This is time critical function!
2835 int c = count;
2836 int empty_space;
2837 int copied = 0;
2838 int i, j;
2839
2840 empty_space = me_circ_buf_space_to_end(&instance->circ_buf);
2841 if (empty_space <= 0) {
2842 PDEBUG("Circular buffer full.\n");
2843 return -ME_ERRNO_RING_BUFFER_OVERFLOW;
2844 }
2845
2846 if (empty_space < c) { //Copy first part. Max to end of buffer.
2847 PDEBUG
2848 ("Try to copy %d values from FIFO to circular buffer (pass 1).\n",
2849 empty_space);
2850 for (i = 0; i < empty_space; i++) {
2851 *(instance->circ_buf.buf + instance->circ_buf.head) =
2852 (inw(instance->data_reg) ^ 0x8000);
2853 instance->circ_buf.head++;
2854 }
2855 instance->circ_buf.head &= instance->circ_buf.mask;
2856 c -= empty_space;
2857 copied = empty_space;
2858
2859 empty_space = me_circ_buf_space_to_end(&instance->circ_buf);
2860 }
2861
2862 if (empty_space > 0) {
2863 j = (empty_space < c) ? empty_space : c;
2864 PDEBUG
2865 ("Try to copy %d values from FIFO to circular buffer (pass 2).\n",
2866 c);
2867 for (i = 0; i < j; i++) {
2868 *(instance->circ_buf.buf + instance->circ_buf.head) =
2869 (inw(instance->data_reg) ^ 0x8000);
2870 instance->circ_buf.head++;
2871 }
2872 instance->circ_buf.head &= instance->circ_buf.mask;
2873 copied += j;
2874 }
2875 return copied;
2876}
2877
2878void inline ai_infinite_ISM(me4600_ai_subdevice_t * instance)
2879{ /// @note This is time critical function!
2880 register volatile uint32_t ctrl_set, ctrl_reset, tmp;
2881
2882 if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) { // Only sample counter with reloadnig is working. Reset it.
2883 PINFO
2884 ("Only sample counter with reloadnig is working. Reset it.\n");
2885 ctrl_set = ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
2886 ctrl_reset = ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
2887 } else if (instance->fifo_irq_threshold == instance->ISM.read) { //This is SC interrupt for large block. The whole section is done. Reset SC_IRQ an HF_IRQ and start everything again from beginning.
2888 PINFO
2889 ("This is SC interrupt for large block. The whole section is done. Reset SC_IRQ an HF_IRQ and start everything again from beginning.\n");
2890 ctrl_set =
2891 ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
2892 ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
2893 ctrl_reset =
2894 ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
2895 ME4600_AI_CTRL_BIT_HF_IRQ_RESET);
2896 } else if (instance->fifo_irq_threshold >= (ME4600_AI_FIFO_MAX_SC + instance->ISM.read)) { //This is HF interrupt for large block.The next interrupt should be from HF, also. Reset HF.
2897 PINFO
2898 ("This is HF interrupt for large block.The next interrupt should be from HF, also. Reset HF.\n");
2899 ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
2900 ctrl_reset = ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
2901 } else { //This is HF interrupt for large block.The next interrupt should be from SC. Don't reset HF!
2902 PINFO
2903 ("This is HF interrupt for large block.The next interrupt should be from SC. Don't reset HF!\n");
2904 ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
2905 ctrl_reset = 0xFFFFFFFF;
2906 }
2907
2908 //Reset interrupt latch.
2909 spin_lock(instance->ctrl_reg_lock);
2910 tmp = inl(instance->ctrl_reg);
2911 PINFO("ctrl=0x%x ctrl_set=0x%x ctrl_reset=0x%x\n", tmp, ctrl_set,
2912 ctrl_reset);
2913 tmp |= ctrl_set;
2914 outl(tmp, instance->ctrl_reg);
2915 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
2916 instance->ctrl_reg - instance->reg_base, tmp);
2917 if (ctrl_reset != 0xFFFFFFFF) {
2918 outl(tmp & ctrl_reset, instance->ctrl_reg);
2919 PDEBUG_REG("ctrl_reset outl(0x%lX+0x%lX)=0x%x\n",
2920 instance->reg_base,
2921 instance->ctrl_reg - instance->reg_base,
2922 tmp & ctrl_reset);
2923 }
2924 spin_unlock(instance->ctrl_reg_lock);
2925
2926}
2927
2928void inline ai_limited_ISM(me4600_ai_subdevice_t * instance,
2929 uint32_t irq_status)
2930{ /// @note This is time critical function!
2931 register volatile uint32_t ctrl_set, ctrl_reset = 0xFFFFFFFF, tmp;
2932
2933 if (!instance->fifo_irq_threshold) { //No threshold provided. SC ends work.
2934 PINFO("No threshold provided. SC ends work.\n");
2935 ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
2936 if (instance->data_required > (ME4600_AI_FIFO_COUNT - 1 + instance->ISM.global_read)) { //HF need reseting.
2937 ctrl_reset &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
2938 }
2939 } else //if(instance->fifo_irq_threshold)
2940 {
2941 if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) {
2942 PINFO("Threshold provided. Clear HF latch.\n");
2943 ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
2944
2945 if (instance->fifo_irq_threshold >= (ME4600_AI_FIFO_MAX_SC + instance->ISM.read)) { //This is not the last one. HF need reseting.
2946 PINFO
2947 ("The next interrupt is HF. HF need be activating.\n");
2948 ctrl_reset = ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
2949 }
2950 }
2951
2952 if (irq_status & ME4600_IRQ_STATUS_BIT_SC) {
2953 PINFO("Threshold provided. Restart SC.\n");
2954 ctrl_set = ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
2955 ctrl_reset &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
2956
2957 if (instance->fifo_irq_threshold >= ME4600_AI_FIFO_MAX_SC) { //This is not the last one. HF need to be activating.
2958 PINFO
2959 ("The next interrupt is HF. HF need to be activating.\n");
2960 ctrl_reset &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
2961 }
2962 }
2963 }
2964
2965 //Reset interrupt latch.
2966 spin_lock(instance->ctrl_reg_lock);
2967 tmp = inl(instance->ctrl_reg);
2968 tmp |= ctrl_set;
2969 outl(tmp, instance->ctrl_reg);
2970 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
2971 instance->ctrl_reg - instance->reg_base, tmp);
2972
2973 if (ctrl_reset != 0xFFFFFFFF) {
2974 outl(tmp & ctrl_reset, instance->ctrl_reg);
2975 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2976 instance->reg_base,
2977 instance->ctrl_reg - instance->reg_base,
2978 tmp & ctrl_reset);
2979 }
2980 spin_unlock(instance->ctrl_reg_lock);
2981
2982}
2983
2984/** @brief Last chunck of datas. We must reschedule sample counter.
2985* @note Last chunck.
2986* Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts.
2987* @warning When threshold is wrongly set some IRQ are lost.(!!!)
2988*/
2989void inline ai_reschedule_SC(me4600_ai_subdevice_t * instance)
2990{
2991 register uint32_t rest;
2992
2993 if (instance->data_required <= instance->ISM.global_read)
2994 return;
2995
2996 rest = instance->data_required - instance->ISM.global_read;
2997 if (rest < instance->fifo_irq_threshold) { //End of work soon ....
2998 PDEBUG("Rescheduling SC from %d to %d.\n",
2999 instance->fifo_irq_threshold, rest);
3000 /// @note Write new value to SC <== DANGER! This is not safe solution! We can miss some inputs.
3001 outl(rest, instance->sample_counter_reg);
3002 PDEBUG_REG("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
3003 instance->reg_base,
3004 instance->sample_counter_reg - instance->reg_base,
3005 rest);
3006 instance->fifo_irq_threshold = rest;
3007
3008 if (rest < ME4600_AI_FIFO_MAX_SC) {
3009 instance->ISM.next = rest;
3010 } else {
3011 instance->ISM.next = rest % ME4600_AI_FIFO_HALF;
3012 if (instance->ISM.next + ME4600_AI_FIFO_HALF <
3013 ME4600_AI_FIFO_MAX_SC) {
3014 instance->ISM.next += ME4600_AI_FIFO_HALF;
3015 }
3016 }
3017 }
3018}
3019
3020/** Start the ISM. All must be reseted before enter to this function. */
3021void inline ai_data_acquisition_logic(me4600_ai_subdevice_t * instance)
3022{
3023 register uint32_t tmp;
3024
3025 if (!instance->data_required) { //This is infinite aqusition.
3026 if (!instance->fifo_irq_threshold) { //No threshold provided. Set SC to 0.5*FIFO. Clear the SC's latch.
3027 //Set the sample counter
3028 outl(ME4600_AI_FIFO_HALF, instance->sample_counter_reg);
3029 PDEBUG_REG
3030 ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
3031 instance->reg_base,
3032 instance->sample_counter_reg - instance->reg_base,
3033 ME4600_AI_FIFO_HALF);
3034 } else { //Threshold provided. Set SC to treshold. Clear the SC's latch.
3035 //Set the sample counter
3036 outl(instance->fifo_irq_threshold,
3037 instance->sample_counter_reg);
3038 PDEBUG_REG
3039 ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
3040 instance->reg_base,
3041 instance->sample_counter_reg - instance->reg_base,
3042 instance->fifo_irq_threshold);
3043 }
3044
3045 if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) { //Enable only sample counter's interrupt. Set reload bit. Clear the SC's latch.
3046 spin_lock(instance->ctrl_reg_lock);
3047 tmp = inl(instance->ctrl_reg);
3048 tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD;
3049 tmp &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
3050 outl(tmp, instance->ctrl_reg);
3051 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3052 instance->reg_base,
3053 instance->ctrl_reg - instance->reg_base,
3054 tmp);
3055 spin_unlock(instance->ctrl_reg_lock);
3056 if (!instance->fifo_irq_threshold) { //No threshold provided. Set ISM.next to 0.5*FIFO.
3057 instance->ISM.next = ME4600_AI_FIFO_HALF;
3058 } else { //Threshold provided. Set ISM.next to treshold.
3059 instance->ISM.next =
3060 instance->fifo_irq_threshold;
3061 }
3062 } else { //Enable sample counter's and HF's interrupts.
3063 spin_lock(instance->ctrl_reg_lock);
3064 tmp = inl(instance->ctrl_reg);
3065 tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD;
3066 tmp &=
3067 ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
3068 ME4600_AI_CTRL_BIT_HF_IRQ_RESET);
3069 outl(tmp, instance->ctrl_reg);
3070 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3071 instance->reg_base,
3072 instance->ctrl_reg - instance->reg_base,
3073 tmp);
3074 spin_unlock(instance->ctrl_reg_lock);
3075
3076 instance->ISM.next =
3077 instance->fifo_irq_threshold % ME4600_AI_FIFO_HALF;
3078 if (instance->ISM.next + ME4600_AI_FIFO_HALF <
3079 ME4600_AI_FIFO_MAX_SC) {
3080 instance->ISM.next += ME4600_AI_FIFO_HALF;
3081 }
3082 }
3083 } else { //This aqusition is limited to set number of data.
3084 if (instance->fifo_irq_threshold >= instance->data_required) { //Stupid situation.
3085 instance->fifo_irq_threshold = 0;
3086 PDEBUG
3087 ("Stupid situation: data_required(%d) < threshold(%d).\n",
3088 instance->fifo_irq_threshold,
3089 instance->data_required);
3090 }
3091
3092 if (!instance->fifo_irq_threshold) { //No threshold provided. Easy case: HF=read and SC=end.
3093 //Set the sample counter to data_required.
3094 outl(instance->data_required,
3095 instance->sample_counter_reg);
3096 PDEBUG_REG
3097 ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
3098 instance->reg_base,
3099 instance->sample_counter_reg - instance->reg_base,
3100 instance->data_required);
3101
3102 //Reset the latches of sample counter and HF (if SC>FIFO).
3103 //No SC reload!
3104 spin_lock(instance->ctrl_reg_lock);
3105 tmp = inl(instance->ctrl_reg);
3106 tmp &=
3107 ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
3108 ME4600_AI_CTRL_BIT_SC_RELOAD);
3109 if (instance->data_required >
3110 (ME4600_AI_FIFO_COUNT - 1)) {
3111 tmp &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
3112 instance->ISM.next =
3113 instance->data_required %
3114 ME4600_AI_FIFO_HALF;
3115 instance->ISM.next += ME4600_AI_FIFO_HALF;
3116
3117 } else {
3118 instance->ISM.next = instance->data_required;
3119 }
3120 outl(tmp, instance->ctrl_reg);
3121 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3122 instance->reg_base,
3123 instance->ctrl_reg - instance->reg_base,
3124 tmp);
3125 spin_unlock(instance->ctrl_reg_lock);
3126
3127 } else { //The most general case. We have concret numbe of required data and threshold. SC=TH
3128 //Set the sample counter to threshold.
3129 outl(instance->fifo_irq_threshold,
3130 instance->sample_counter_reg);
3131 PDEBUG_REG
3132 ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
3133 instance->reg_base,
3134 instance->sample_counter_reg - instance->reg_base,
3135 instance->fifo_irq_threshold);
3136
3137 spin_lock(instance->ctrl_reg_lock);
3138 tmp = inl(instance->ctrl_reg);
3139 //In this moment we are sure that SC will come more than once.
3140 tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD;
3141
3142 if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) { //The threshold is so small that we do need HF.
3143 tmp &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
3144 instance->ISM.next =
3145 instance->fifo_irq_threshold;
3146 } else { //The threshold is large. The HF must be use.
3147 tmp &=
3148 ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
3149 ME4600_AI_CTRL_BIT_HF_IRQ_RESET);
3150 instance->ISM.next =
3151 instance->fifo_irq_threshold %
3152 ME4600_AI_FIFO_HALF;
3153 if (instance->ISM.next + ME4600_AI_FIFO_HALF <
3154 ME4600_AI_FIFO_MAX_SC) {
3155 instance->ISM.next +=
3156 ME4600_AI_FIFO_HALF;
3157 }
3158 }
3159 outl(tmp, instance->ctrl_reg);
3160 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3161 instance->reg_base,
3162 instance->ctrl_reg - instance->reg_base,
3163 tmp);
3164 spin_unlock(instance->ctrl_reg_lock);
3165 }
3166 }
3167}
3168
3169static int ai_mux_toggler(me4600_ai_subdevice_t * instance)
3170{
3171 uint32_t tmp;
3172
3173 PDEBUG("executed. idx=0\n");
3174
3175 outl(0, instance->scan_pre_timer_low_reg);
3176 PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
3177 instance->reg_base,
3178 instance->scan_pre_timer_low_reg - instance->reg_base, 0);
3179 outl(0, instance->scan_pre_timer_high_reg);
3180 PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
3181 instance->reg_base,
3182 instance->scan_pre_timer_high_reg - instance->reg_base, 0);
3183 outl(0, instance->scan_timer_low_reg);
3184 PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
3185 instance->reg_base,
3186 instance->scan_timer_low_reg - instance->reg_base, 0);
3187 outl(0, instance->scan_timer_high_reg);
3188 PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
3189 instance->reg_base,
3190 instance->scan_timer_high_reg - instance->reg_base, 0);
3191 outl(65, instance->chan_timer_reg);
3192 PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
3193 instance->reg_base,
3194 instance->chan_timer_reg - instance->reg_base, 65);
3195 outl(65, instance->chan_pre_timer_reg);
3196 PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
3197 instance->reg_base,
3198 instance->chan_pre_timer_reg - instance->reg_base, 65);
3199
3200 // Turn on internal reference.
3201 tmp = inl(instance->ctrl_reg);
3202 tmp |= ME4600_AI_CTRL_BIT_FULLSCALE;
3203 outl(tmp, instance->ctrl_reg);
3204 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
3205 instance->ctrl_reg - instance->reg_base, tmp);
3206
3207 // Clear data and channel fifo.
3208 tmp &=
3209 ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
3210 outl(tmp, instance->ctrl_reg);
3211 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
3212 instance->ctrl_reg - instance->reg_base, tmp);
3213 tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
3214 outl(tmp, instance->ctrl_reg);
3215 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
3216 instance->ctrl_reg - instance->reg_base, tmp);
3217
3218 // Write channel entry.
3219 outl(ME4600_AI_LIST_INPUT_DIFFERENTIAL |
3220 ME4600_AI_LIST_RANGE_UNIPOLAR_2_5 | 31,
3221 instance->channel_list_reg);
3222 PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
3223 instance->reg_base,
3224 instance->channel_list_reg - instance->reg_base,
3225 ME4600_AI_LIST_INPUT_DIFFERENTIAL |
3226 ME4600_AI_LIST_RANGE_UNIPOLAR_2_5 | 31);
3227
3228 // Start conversion.
3229 inl(instance->start_reg);
3230 PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
3231 instance->start_reg - instance->reg_base);
3232 udelay(10);
3233
3234 // Clear data and channel fifo.
3235 tmp &=
3236 ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
3237 outl(tmp, instance->ctrl_reg);
3238 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
3239 instance->ctrl_reg - instance->reg_base, tmp);
3240 tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
3241 outl(tmp, instance->ctrl_reg);
3242 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
3243 instance->ctrl_reg - instance->reg_base, tmp);
3244
3245 // Write channel entry.
3246 // ME4600_AI_LIST_INPUT_SINGLE_ENDED | ME4600_AI_LIST_RANGE_BIPOLAR_10 <= 0x0000
3247 outl(ME4600_AI_LIST_INPUT_SINGLE_ENDED |
3248 ME4600_AI_LIST_RANGE_BIPOLAR_10, instance->channel_list_reg);
3249 PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
3250 instance->reg_base,
3251 instance->channel_list_reg - instance->reg_base,
3252 ME4600_AI_LIST_INPUT_SINGLE_ENDED |
3253 ME4600_AI_LIST_RANGE_BIPOLAR_10);
3254
3255 // Start conversion.
3256 inl(instance->start_reg);
3257 PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
3258 instance->start_reg - instance->reg_base);
3259 udelay(10);
3260
3261 // Clear control register.
3262 tmp &= (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
3263 outl(tmp, instance->ctrl_reg);
3264 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
3265 instance->ctrl_reg - instance->reg_base, tmp);
3266
3267 return ME_ERRNO_SUCCESS;
3268}
3269
3270/** @brief Copy rest of data from fifo to circular buffer.
3271* @note Helper for STOP command. After FSM is stopped.
3272* @note This is slow function that copy all remainig data from FIFO to buffer.
3273*
3274* @param instance The subdevice instance (pointer).
3275*
3276* @return On success: Number of copied values.
3277* @return On error: Negative error code -ME_ERRNO_RING_BUFFER_OVERFLOW.
3278*/
3279static int inline ai_read_data_pooling(me4600_ai_subdevice_t * instance)
3280{ /// @note This is time critical function!
3281 int empty_space;
3282 int copied = 0;
3283 int status = ME_ERRNO_SUCCESS;
3284
3285 PDEBUG("Space left in circular buffer = %d.\n",
3286 me_circ_buf_space(&instance->circ_buf));
3287
3288 while ((empty_space = me_circ_buf_space(&instance->circ_buf))) {
3289 if (!(status = inl(instance->status_reg) & ME4600_AI_STATUS_BIT_EF_DATA)) { //No more data. status = ME_ERRNO_SUCCESS = 0
3290 break;
3291 }
3292 *(instance->circ_buf.buf + instance->circ_buf.head) =
3293 (inw(instance->data_reg) ^ 0x8000);
3294 instance->circ_buf.head++;
3295 instance->circ_buf.head &= instance->circ_buf.mask;
3296 }
3297
3298#ifdef MEDEBUG_ERROR
3299 if (!status)
3300 PDEBUG
3301 ("Copied all remaining datas (%d) from FIFO to circular buffer.\n",
3302 copied);
3303 else {
3304 PDEBUG("No more empty space in buffer.\n");
3305 PDEBUG("Copied %d datas from FIFO to circular buffer.\n",
3306 copied);
3307 PDEBUG("FIFO still not empty.\n");
3308 }
3309#endif
3310 return (!status) ? copied : -ME_ERRNO_RING_BUFFER_OVERFLOW;
3311}
3312
3313#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
3314static void me4600_ai_work_control_task(void *subdevice)
3315#else
3316static void me4600_ai_work_control_task(struct work_struct *work)
3317#endif
3318{
3319 me4600_ai_subdevice_t *instance;
3320 uint32_t status;
3321 uint32_t ctrl;
3322 unsigned long cpu_flags = 0;
3323 int reschedule = 0;
3324 int signaling = 0;
3325
3326#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
3327 instance = (me4600_ai_subdevice_t *) subdevice;
3328#else
3329 instance =
3330 container_of((void *)work, me4600_ai_subdevice_t, ai_control_task);
3331#endif
3332 PINFO("<%s: %ld> executed.\n", __FUNCTION__, jiffies);
3333
3334 status = inl(instance->status_reg);
3335 PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
3336 instance->status_reg - instance->reg_base, status);
3337
3338 switch (instance->status) { // Checking actual mode.
3339 // Not configured for work.
3340 case ai_status_none:
3341 break;
3342
3343 //This are stable modes. No need to do anything. (?)
3344 case ai_status_single_configured:
3345 case ai_status_stream_configured:
3346 case ai_status_stream_fifo_error:
3347 case ai_status_stream_buffer_error:
3348 case ai_status_stream_error:
3349 PERROR("Shouldn't be running!.\n");
3350 break;
3351
3352 // Stream modes
3353 case ai_status_stream_run_wait:
3354 if (status & ME4600_AI_STATUS_BIT_FSM) { // ISM started..
3355 instance->status = ai_status_stream_run;
3356 // Signal the end of wait for start.
3357 signaling = 1;
3358 // Wait now for stop.
3359 reschedule = 1;
3360 break;
3361
3362 // Check timeout.
3363 if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
3364 PDEBUG("Timeout reached.\n");
3365 // Stop all actions. No conditions! Block interrupts. Reset FIFO => Too late!
3366 ai_stop_isr(instance);
3367
3368 instance->status = ai_status_stream_end;
3369
3370 // Signal the end.
3371 signaling = 1;
3372 }
3373 }
3374 break;
3375
3376 case ai_status_stream_run:
3377 // Wait for stop ISM.
3378 reschedule = 1;
3379 break;
3380
3381 case ai_status_stream_end_wait:
3382 if (!(status & ME4600_AI_STATUS_BIT_FSM)) { // ISM stoped. Overwrite ISR.
3383 instance->status = ai_status_stream_end;
3384 // Signal the end of wait for stop.
3385 signaling = 1;
3386 } else {
3387 // Wait for stop ISM.
3388 reschedule = 1;
3389 }
3390 break;
3391
3392 case ai_status_stream_end:
3393 //End work.
3394 if (status & ME4600_AI_STATUS_BIT_FSM) { // Still working? Stop it!
3395 PERROR
3396 ("Status is 'ai_status_stream_end' but hardware is still working!\n");
3397 spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
3398 ctrl = inl(instance->ctrl_reg);
3399 ctrl |=
3400 (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP |
3401 ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
3402 ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
3403 outl(ctrl, instance->ctrl_reg);
3404 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3405 instance->reg_base,
3406 instance->ctrl_reg - instance->reg_base,
3407 ctrl);
3408 spin_unlock_irqrestore(instance->ctrl_reg_lock,
3409 cpu_flags);
3410 }
3411 break;
3412
3413 default:
3414 PERROR_CRITICAL("Status is in wrong state (%d)!\n",
3415 instance->status);
3416 instance->status = ai_status_stream_error;
3417 // Signal the end.
3418 signaling = 1;
3419 break;
3420
3421 }
3422
3423 if (signaling) { //Signal it.
3424 wake_up_interruptible_all(&instance->wait_queue);
3425 }
3426
3427 if (instance->ai_control_task_flag && reschedule) { // Reschedule task
3428 queue_delayed_work(instance->me4600_workqueue,
3429 &instance->ai_control_task, 1);
3430 } else {
3431 PINFO("<%s> Ending control task.\n", __FUNCTION__);
3432 }
3433
3434}
diff --git a/drivers/staging/meilhaus/me4600_ai.h b/drivers/staging/meilhaus/me4600_ai.h
new file mode 100644
index 000000000000..1d5a1b9c6f91
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_ai.h
@@ -0,0 +1,180 @@
1/**
2 * @file me4600_ai.h
3 *
4 * @brief Meilhaus ME-4000 analog input subdevice class.
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 _ME4600_AI_H_
29#define _ME4600_AI_H_
30
31#include <linux/version.h>
32#include "mesubdevice.h"
33#include "meioctl.h"
34#include "mecirc_buf.h"
35
36#ifdef __KERNEL__
37
38#define ME4600_AI_MAX_DATA 0xFFFF
39
40#ifdef ME_SYNAPSE
41# define ME4600_AI_CIRC_BUF_SIZE_ORDER 8 // 2^n PAGES =>> Maximum value of 1MB for Synapse
42#else
43# define ME4600_AI_CIRC_BUF_SIZE_ORDER 5 // 2^n PAGES =>> 128KB
44#endif
45#define ME4600_AI_CIRC_BUF_SIZE PAGE_SIZE<<ME4600_AI_CIRC_BUF_SIZE_ORDER // Buffer size in bytes.
46
47#ifdef _CBUFF_32b_t
48# define ME4600_AI_CIRC_BUF_COUNT ((ME4600_AI_CIRC_BUF_SIZE) / sizeof(uint32_t)) // Size in values
49#else
50# define ME4600_AI_CIRC_BUF_COUNT ((ME4600_AI_CIRC_BUF_SIZE) / sizeof(uint16_t)) // Size in values
51#endif
52
53#define ME4600_AI_FIFO_HALF 1024 //ME4600_AI_FIFO_COUNT/2 //1024
54#define ME4600_AI_FIFO_MAX_SC 1352 //0.66*ME4600_AI_FIFO_COUNT //1352
55
56typedef enum ME4600_AI_STATUS {
57 ai_status_none = 0,
58 ai_status_single_configured,
59 ai_status_stream_configured,
60 ai_status_stream_run_wait,
61 ai_status_stream_run,
62 ai_status_stream_end_wait,
63 ai_status_stream_end,
64 ai_status_stream_fifo_error,
65 ai_status_stream_buffer_error,
66 ai_status_stream_error,
67 ai_status_last
68} ME4600_AI_STATUS;
69
70typedef struct me4600_single_config_entry {
71 unsigned short status;
72 uint32_t entry;
73 uint32_t ctrl;
74} me4600_single_config_entry_t;
75
76typedef struct me4600_range_entry {
77 int min;
78 int max;
79} me4600_range_entry_t;
80
81typedef struct me4600_ai_ISM {
82 volatile unsigned int global_read; /**< The number of data read in total. */
83 volatile unsigned int read; /**< The number of data read for this chunck. */
84 volatile unsigned int next; /**< The number of data request by user. */
85} me4600_ai_ISM_t;
86
87typedef struct me4600_ai_timeout {
88 unsigned long start_time;
89 unsigned long delay;
90} me4600_ai_timeout_t;
91
92/**
93 * @brief The ME-4000 analog input subdevice class.
94 */
95typedef struct me4600_ai_subdevice {
96 /* Inheritance */
97 me_subdevice_t base; /**< The subdevice base class. */
98
99 /* Attributes */
100 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
101 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
102
103 /* Hardware feautres */
104 unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */
105 int isolated; /**< Marks if this subdevice is on an optoisolated device. */
106 int sh; /**< Marks if this subdevice has sample and hold devices. */
107
108 unsigned int channels; /**< The number of channels available on this subdevice. */
109 me4600_single_config_entry_t single_config[32]; /**< The configuration set for single acquisition. */
110
111 unsigned int data_required; /**< The number of data request by user. */
112 unsigned int fifo_irq_threshold; /**< The user adjusted FIFO high water interrupt level. */
113 unsigned int chan_list_len; /**< The length of the user defined channel list. */
114
115 me4600_ai_ISM_t ISM; /**< The information request by Interrupt-State-Machine. */
116 volatile enum ME4600_AI_STATUS status; /**< The current stream status flag. */
117 me4600_ai_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
118
119 /* Registers *//**< All registers are 32 bits long. */
120 unsigned long ctrl_reg;
121 unsigned long status_reg;
122 unsigned long channel_list_reg;
123 unsigned long data_reg;
124 unsigned long chan_timer_reg;
125 unsigned long chan_pre_timer_reg;
126 unsigned long scan_timer_low_reg;
127 unsigned long scan_timer_high_reg;
128 unsigned long scan_pre_timer_low_reg;
129 unsigned long scan_pre_timer_high_reg;
130 unsigned long start_reg;
131 unsigned long irq_status_reg;
132 unsigned long sample_counter_reg;
133
134 unsigned int ranges_len;
135 me4600_range_entry_t ranges[4]; /**< The ranges available on this subdevice. */
136
137 /* Software buffer */
138 me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. */
139 wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
140
141 struct workqueue_struct *me4600_workqueue;
142#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
143 struct work_struct ai_control_task;
144#else
145 struct delayed_work ai_control_task;
146#endif
147
148 volatile int ai_control_task_flag; /**< Flag controling reexecuting of control task */
149
150#ifdef MEDEBUG_DEBUG_REG
151 unsigned long reg_base;
152#endif
153} me4600_ai_subdevice_t;
154
155/**
156 * @brief The constructor to generate a ME-4000 analog input subdevice instance.
157 *
158 * @param reg_base The register base address of the device as returned by the PCI BIOS.
159 * @param channels The number of analog input channels available on this subdevice.
160 * @param channels The number of analog input ranges available on this subdevice.
161 * @param isolated Flag indicating if this device is opto isolated.
162 * @param sh Flag indicating if sample and hold devices are available.
163 * @param irq The irq number assigned by PCI BIOS.
164 * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
165 *
166 * @return Pointer to new instance on success.\n
167 * NULL on error.
168 */
169me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base,
170 unsigned int channels,
171 unsigned int ranges,
172 int isolated,
173 int sh,
174 int irq,
175 spinlock_t * ctrl_reg_lock,
176 struct workqueue_struct
177 *me4600_wq);
178
179#endif
180#endif
diff --git a/drivers/staging/meilhaus/me4600_ai_reg.h b/drivers/staging/meilhaus/me4600_ai_reg.h
new file mode 100644
index 000000000000..083fac7685f5
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_ai_reg.h
@@ -0,0 +1,107 @@
1/**
2 * @file me4600_ai_reg.h
3 *
4 * @brief ME-4000 analog input subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME4600_AI_REG_H_
28#define _ME4600_AI_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME4600_AI_CTRL_REG 0x74 // _/W
33#define ME4600_AI_STATUS_REG 0x74 // R/_
34#define ME4600_AI_CHANNEL_LIST_REG 0x78 // _/W
35#define ME4600_AI_DATA_REG 0x7C // R/_
36#define ME4600_AI_CHAN_TIMER_REG 0x80 // _/W
37#define ME4600_AI_CHAN_PRE_TIMER_REG 0x84 // _/W
38#define ME4600_AI_SCAN_TIMER_LOW_REG 0x88 // _/W
39#define ME4600_AI_SCAN_TIMER_HIGH_REG 0x8C // _/W
40#define ME4600_AI_SCAN_PRE_TIMER_LOW_REG 0x90 // _/W
41#define ME4600_AI_SCAN_PRE_TIMER_HIGH_REG 0x94 // _/W
42#define ME4600_AI_START_REG 0x98 // R/_
43
44#define ME4600_AI_SAMPLE_COUNTER_REG 0xC0 // _/W
45
46#define ME4600_AI_CTRL_BIT_MODE_0 0x00000001
47#define ME4600_AI_CTRL_BIT_MODE_1 0x00000002
48#define ME4600_AI_CTRL_BIT_MODE_2 0x00000004
49#define ME4600_AI_CTRL_BIT_SAMPLE_HOLD 0x00000008
50#define ME4600_AI_CTRL_BIT_IMMEDIATE_STOP 0x00000010
51#define ME4600_AI_CTRL_BIT_STOP 0x00000020
52#define ME4600_AI_CTRL_BIT_CHANNEL_FIFO 0x00000040
53#define ME4600_AI_CTRL_BIT_DATA_FIFO 0x00000080
54#define ME4600_AI_CTRL_BIT_FULLSCALE 0x00000100
55#define ME4600_AI_CTRL_BIT_OFFSET 0x00000200
56#define ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG 0x00000400
57#define ME4600_AI_CTRL_BIT_EX_TRIG 0x00000800
58#define ME4600_AI_CTRL_BIT_EX_TRIG_FALLING 0x00001000
59#define ME4600_AI_CTRL_BIT_EX_IRQ 0x00002000
60#define ME4600_AI_CTRL_BIT_EX_IRQ_RESET 0x00004000
61#define ME4600_AI_CTRL_BIT_LE_IRQ 0x00008000
62#define ME4600_AI_CTRL_BIT_LE_IRQ_RESET 0x00010000
63#define ME4600_AI_CTRL_BIT_HF_IRQ 0x00020000
64#define ME4600_AI_CTRL_BIT_HF_IRQ_RESET 0x00040000
65#define ME4600_AI_CTRL_BIT_SC_IRQ 0x00080000
66#define ME4600_AI_CTRL_BIT_SC_IRQ_RESET 0x00100000
67#define ME4600_AI_CTRL_BIT_SC_RELOAD 0x00200000
68#define ME4600_AI_CTRL_BIT_EX_TRIG_BOTH 0x80000000
69
70#define ME4600_AI_STATUS_BIT_EF_CHANNEL 0x00400000
71#define ME4600_AI_STATUS_BIT_HF_CHANNEL 0x00800000
72#define ME4600_AI_STATUS_BIT_FF_CHANNEL 0x01000000
73#define ME4600_AI_STATUS_BIT_EF_DATA 0x02000000
74#define ME4600_AI_STATUS_BIT_HF_DATA 0x04000000
75#define ME4600_AI_STATUS_BIT_FF_DATA 0x08000000
76#define ME4600_AI_STATUS_BIT_LE 0x10000000
77#define ME4600_AI_STATUS_BIT_FSM 0x20000000
78
79#define ME4600_AI_CTRL_RPCI_FIFO 0x40000000 //Always set to zero!
80
81#define ME4600_AI_BASE_FREQUENCY 33E6
82
83#define ME4600_AI_MIN_ACQ_TICKS 66LL
84#define ME4600_AI_MAX_ACQ_TICKS 0xFFFFFFFFLL
85
86#define ME4600_AI_MIN_SCAN_TICKS 66LL
87#define ME4600_AI_MAX_SCAN_TICKS 0xFFFFFFFFFLL
88
89#define ME4600_AI_MIN_CHAN_TICKS 66LL
90#define ME4600_AI_MAX_CHAN_TICKS 0xFFFFFFFFLL
91
92#define ME4600_AI_FIFO_COUNT 2048
93
94#define ME4600_AI_LIST_COUNT 1024
95
96#define ME4600_AI_LIST_INPUT_SINGLE_ENDED 0x000
97#define ME4600_AI_LIST_INPUT_DIFFERENTIAL 0x020
98
99#define ME4600_AI_LIST_RANGE_BIPOLAR_10 0x000
100#define ME4600_AI_LIST_RANGE_BIPOLAR_2_5 0x040
101#define ME4600_AI_LIST_RANGE_UNIPOLAR_10 0x080
102#define ME4600_AI_LIST_RANGE_UNIPOLAR_2_5 0x0C0
103
104#define ME4600_AI_LIST_LAST_ENTRY 0x100
105
106#endif
107#endif
diff --git a/drivers/staging/meilhaus/me4600_ao.c b/drivers/staging/meilhaus/me4600_ao.c
new file mode 100644
index 000000000000..2c92e655a81e
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_ao.c
@@ -0,0 +1,6011 @@
1/**
2 * @file me4600_ao.c
3 *
4 * @brief ME-4000 analog output 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///Common part. (For normal and Bosch builds.)
33
34/* Includes
35 */
36
37#include <linux/module.h>
38
39#include <linux/slab.h>
40#include <linux/spinlock.h>
41#include <asm/io.h>
42#include <asm/uaccess.h>
43#include <linux/types.h>
44#include <linux/version.h>
45#include <linux/interrupt.h>
46#include <linux/delay.h>
47
48#include "medefines.h"
49#include "meinternal.h"
50#include "meerror.h"
51
52#include "medebug.h"
53#include "meids.h"
54#include "me4600_reg.h"
55#include "me4600_ao_reg.h"
56#include "me4600_ao.h"
57
58/* Defines
59 */
60
61static int me4600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
62 int unit,
63 int *min,
64 int *max, int *maxdata, int *range);
65
66static int me4600_ao_query_number_ranges(me_subdevice_t * subdevice,
67 int unit, int *count);
68
69static int me4600_ao_query_range_info(me_subdevice_t * subdevice,
70 int range,
71 int *unit,
72 int *min, int *max, int *maxdata);
73
74static int me4600_ao_query_timer(me_subdevice_t * subdevice,
75 int timer,
76 int *base_frequency,
77 long long *min_ticks, long long *max_ticks);
78
79static int me4600_ao_query_number_channels(me_subdevice_t * subdevice,
80 int *number);
81
82static int me4600_ao_query_subdevice_type(me_subdevice_t * subdevice,
83 int *type, int *subtype);
84
85static int me4600_ao_query_subdevice_caps(me_subdevice_t * subdevice,
86 int *caps);
87
88static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
89 int cap, int *args, int count);
90
91#ifndef BOSCH
92/// @note NORMAL BUILD
93/// @author Krzysztof Gantzke (k.gantzke@meilhaus.de)
94/* Includes
95 */
96
97# include <linux/workqueue.h>
98
99/* Defines
100 */
101
102/** Remove subdevice.
103*/
104static void me4600_ao_destructor(struct me_subdevice *subdevice);
105
106/** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'.
107*/
108static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
109 struct file *filep, int flags);
110
111/** Set output as single
112*/
113static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
114 struct file *filep,
115 int channel,
116 int single_config,
117 int ref,
118 int trig_chan,
119 int trig_type, int trig_edge, int flags);
120
121/** Pass to user actual value of output.
122*/
123static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
124 struct file *filep,
125 int channel,
126 int *value, int time_out, int flags);
127
128/** Write to output requed value.
129*/
130static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
131 struct file *filep,
132 int channel,
133 int value, int time_out, int flags);
134
135/** Set output as streamed device.
136*/
137static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
138 struct file *filep,
139 meIOStreamConfig_t * config_list,
140 int count,
141 meIOStreamTrigger_t * trigger,
142 int fifo_irq_threshold, int flags);
143
144/** Wait for / Check empty space in buffer.
145*/
146static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
147 struct file *filep,
148 int time_out, int *count, int flags);
149
150/** Start streaming.
151*/
152static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
153 struct file *filep,
154 int start_mode, int time_out, int flags);
155
156/** Check actual state. / Wait for end.
157*/
158static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
159 struct file *filep,
160 int wait,
161 int *status, int *values, int flags);
162
163/** Stop streaming.
164*/
165static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
166 struct file *filep,
167 int stop_mode, int flags);
168
169/** Write datas to buffor.
170*/
171static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
172 struct file *filep,
173 int write_mode,
174 int *values, int *count, int flags);
175
176/** Interrupt handler. Copy from buffer to FIFO.
177*/
178static irqreturn_t me4600_ao_isr(int irq, void *dev_id
179#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
180 , struct pt_regs *regs
181#endif
182 );
183/** Copy data from circular buffer to fifo (fast) in wraparound mode.
184*/
185int inline ao_write_data_wraparound(me4600_ao_subdevice_t * instance, int count,
186 int start_pos);
187
188/** Copy data from circular buffer to fifo (fast).
189*/
190int inline ao_write_data(me4600_ao_subdevice_t * instance, int count,
191 int start_pos);
192
193/** Copy data from circular buffer to fifo (slow).
194*/
195int inline ao_write_data_pooling(me4600_ao_subdevice_t * instance, int count,
196 int start_pos);
197
198/** Copy data from user space to circular buffer.
199*/
200int inline ao_get_data_from_user(me4600_ao_subdevice_t * instance, int count,
201 int *user_values);
202
203/** Stop presentation. Preserve FIFOs.
204*/
205int inline ao_stop_immediately(me4600_ao_subdevice_t * instance);
206
207/** Task for asynchronical state verifying.
208*/
209static void me4600_ao_work_control_task(
210#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
211 void *subdevice
212#else
213 struct work_struct *work
214#endif
215 );
216/* Functions
217 */
218
219static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
220 struct file *filep, int flags)
221{
222 me4600_ao_subdevice_t *instance;
223 int err = ME_ERRNO_SUCCESS;
224 uint32_t tmp;
225
226 instance = (me4600_ao_subdevice_t *) subdevice;
227
228 PDEBUG("executed. idx=%d\n", instance->ao_idx);
229
230 if (flags) {
231 PERROR("Invalid flag specified.\n");
232 return ME_ERRNO_INVALID_FLAGS;
233 }
234
235 ME_SUBDEVICE_ENTER;
236
237 instance->status = ao_status_none;
238 instance->ao_control_task_flag = 0;
239 cancel_delayed_work(&instance->ao_control_task);
240 instance->timeout.delay = 0;
241 instance->timeout.start_time = jiffies;
242
243 //Stop state machine.
244 err = ao_stop_immediately(instance);
245
246 //Remove from synchronous start.
247 spin_lock(instance->preload_reg_lock);
248 tmp = inl(instance->preload_reg);
249 tmp &=
250 ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->
251 ao_idx);
252 outl(tmp, instance->preload_reg);
253 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
254 instance->preload_reg - instance->reg_base, tmp);
255 *instance->preload_flags &=
256 ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->
257 ao_idx);
258 spin_unlock(instance->preload_reg_lock);
259
260 //Set single mode, dissable FIFO, dissable external trigger, set output to analog, block interrupt.
261 outl(ME4600_AO_MODE_SINGLE | ME4600_AO_CTRL_BIT_STOP |
262 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_RESET_IRQ,
263 instance->ctrl_reg);
264 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
265 instance->ctrl_reg - instance->reg_base,
266 ME4600_AO_MODE_SINGLE | ME4600_AO_CTRL_BIT_STOP |
267 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
268 ME4600_AO_CTRL_BIT_RESET_IRQ);
269
270 //Set output to 0V
271 outl(0x8000, instance->single_reg);
272 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
273 instance->single_reg - instance->reg_base, 0x8000);
274
275 instance->circ_buf.head = 0;
276 instance->circ_buf.tail = 0;
277 instance->preloaded_count = 0;
278 instance->data_count = 0;
279 instance->single_value = 0x8000;
280 instance->single_value_in_fifo = 0x8000;
281
282 //Set status to signal that device is unconfigured.
283 instance->status = ao_status_none;
284
285 //Signal reset if user is on wait.
286 wake_up_interruptible_all(&instance->wait_queue);
287
288 ME_SUBDEVICE_EXIT;
289
290 return err;
291}
292
293static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
294 struct file *filep,
295 int channel,
296 int single_config,
297 int ref,
298 int trig_chan,
299 int trig_type, int trig_edge, int flags)
300{
301 me4600_ao_subdevice_t *instance;
302 int err = ME_ERRNO_SUCCESS;
303 uint32_t ctrl;
304 uint32_t sync;
305 unsigned long cpu_flags;
306
307 instance = (me4600_ao_subdevice_t *) subdevice;
308
309 PDEBUG("executed. idx=%d\n", instance->ao_idx);
310
311 // Checking parameters
312 if (flags) {
313 PERROR
314 ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n");
315 return ME_ERRNO_INVALID_FLAGS;
316 }
317
318 switch (trig_type) {
319 case ME_TRIG_TYPE_SW:
320 if (trig_edge != ME_TRIG_EDGE_NONE) {
321 PERROR
322 ("Invalid trigger edge. Software trigger has not edge.\n");
323 return ME_ERRNO_INVALID_TRIG_EDGE;
324 }
325 break;
326
327 case ME_TRIG_TYPE_EXT_DIGITAL:
328 switch (trig_edge) {
329 case ME_TRIG_EDGE_ANY:
330 case ME_TRIG_EDGE_RISING:
331 case ME_TRIG_EDGE_FALLING:
332 break;
333
334 default:
335 PERROR("Invalid trigger edge.\n");
336 return ME_ERRNO_INVALID_TRIG_EDGE;
337 }
338 break;
339
340 default:
341 PERROR
342 ("Invalid trigger type. Trigger must be software or digital.\n");
343 return ME_ERRNO_INVALID_TRIG_TYPE;
344 }
345
346 if ((trig_chan != ME_TRIG_CHAN_DEFAULT)
347 && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) {
348 PERROR("Invalid trigger channel specified.\n");
349 return ME_ERRNO_INVALID_TRIG_CHAN;
350 }
351
352 if (ref != ME_REF_AO_GROUND) {
353 PERROR
354 ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n");
355 return ME_ERRNO_INVALID_REF;
356 }
357
358 if (single_config != 0) {
359 PERROR
360 ("Invalid single config specified. Only one range for anlog outputs is available.\n");
361 return ME_ERRNO_INVALID_SINGLE_CONFIG;
362 }
363
364 if (channel != 0) {
365 PERROR
366 ("Invalid channel number specified. Analog output have only one channel.\n");
367 return ME_ERRNO_INVALID_CHANNEL;
368 }
369
370 ME_SUBDEVICE_ENTER;
371
372 //Subdevice running in stream mode!
373 if ((instance->status >= ao_status_stream_run_wait)
374 && (instance->status < ao_status_stream_end)) {
375 PERROR("Subdevice is busy.\n");
376 ME_SUBDEVICE_EXIT;
377
378 return ME_ERRNO_SUBDEVICE_BUSY;
379 }
380/// @note For single all calls (config and write) are erasing previous state!
381
382 instance->status = ao_status_none;
383
384 // Correct single mirrors
385 instance->single_value_in_fifo = instance->single_value;
386
387 //Stop device
388 err = ao_stop_immediately(instance);
389 if (err) {
390 PERROR_CRITICAL("FSM IS BUSY!\n");
391 ME_SUBDEVICE_EXIT;
392
393 return ME_ERRNO_SUBDEVICE_BUSY;
394 }
395 // Set control register.
396 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
397 // Set stop bit. Stop streaming mode.
398 ctrl = inl(instance->ctrl_reg);
399 //Reset all bits.
400 ctrl = ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP;
401
402 if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) {
403 PINFO("External digital trigger.\n");
404
405 if (trig_edge == ME_TRIG_EDGE_ANY) {
406// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
407 instance->ctrl_trg =
408 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
409 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
410 } else if (trig_edge == ME_TRIG_EDGE_FALLING) {
411// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
412 instance->ctrl_trg = ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
413 } else if (trig_edge == ME_TRIG_EDGE_RISING) {
414 instance->ctrl_trg = 0x0;
415 }
416 } else if (trig_type == ME_TRIG_TYPE_SW) {
417 PDEBUG("Software trigger\n");
418 instance->ctrl_trg = 0x0;
419 }
420
421 outl(ctrl, instance->ctrl_reg);
422 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
423 instance->ctrl_reg - instance->reg_base, ctrl);
424 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
425
426 // Set preload/synchronization register.
427 spin_lock(instance->preload_reg_lock);
428 if (trig_type == ME_TRIG_TYPE_SW) {
429 *instance->preload_flags &=
430 ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx);
431 } else //if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL)
432 {
433 *instance->preload_flags |=
434 ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx;
435 }
436
437 if (trig_chan == ME_TRIG_CHAN_DEFAULT) {
438 *instance->preload_flags &=
439 ~(ME4600_AO_SYNC_HOLD << instance->ao_idx);
440 } else //if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS)
441 {
442 *instance->preload_flags |=
443 ME4600_AO_SYNC_HOLD << instance->ao_idx;
444 }
445
446 //Reset hardware register
447 sync = inl(instance->preload_reg);
448 PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
449 instance->preload_reg - instance->reg_base, sync);
450 sync &= ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx);
451 sync |= ME4600_AO_SYNC_HOLD << instance->ao_idx;
452
453 //Output configured in default (safe) mode.
454 outl(sync, instance->preload_reg);
455 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
456 instance->preload_reg - instance->reg_base, sync);
457 spin_unlock(instance->preload_reg_lock);
458
459 instance->status = ao_status_single_configured;
460
461 ME_SUBDEVICE_EXIT;
462
463 return err;
464}
465
466static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
467 struct file *filep,
468 int channel,
469 int *value, int time_out, int flags)
470{
471 me4600_ao_subdevice_t *instance;
472 int err = ME_ERRNO_SUCCESS;
473
474 unsigned long j;
475 unsigned long delay = 0;
476
477 instance = (me4600_ao_subdevice_t *) subdevice;
478
479 PDEBUG("executed. idx=%d\n", instance->ao_idx);
480
481 if (flags & ~ME_IO_SINGLE_NONBLOCKING) {
482 PERROR("Invalid flag specified. %d\n", flags);
483 return ME_ERRNO_INVALID_FLAGS;
484 }
485
486 if (time_out < 0) {
487 PERROR("Invalid timeout specified.\n");
488 return ME_ERRNO_INVALID_TIMEOUT;
489 }
490
491 if (channel != 0) {
492 PERROR("Invalid channel number specified.\n");
493 return ME_ERRNO_INVALID_CHANNEL;
494 }
495
496 if ((instance->status >= ao_status_stream_configured)
497 && (instance->status <= ao_status_stream_end)) {
498 PERROR("Subdevice not configured to work in single mode!\n");
499 return ME_ERRNO_PREVIOUS_CONFIG;
500 }
501
502 ME_SUBDEVICE_ENTER;
503 if ((!flags) && (instance->status == ao_status_single_run_wait)) { //Blocking mode. Wait for trigger.
504 if (time_out) {
505 delay = (time_out * HZ) / 1000;
506 if (delay == 0)
507 delay = 1;
508 }
509
510 j = jiffies;
511
512 //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
513 wait_event_interruptible_timeout(instance->wait_queue,
514 (instance->status !=
515 ao_status_single_run_wait),
516 (delay) ? delay +
517 1 : LONG_MAX);
518
519 if (instance->status == ao_status_none) {
520 PDEBUG("Single canceled.\n");
521 err = ME_ERRNO_CANCELLED;
522 }
523
524 if (signal_pending(current)) {
525 PERROR("Wait on start of state machine interrupted.\n");
526 instance->status = ao_status_none;
527 ao_stop_immediately(instance);
528 err = ME_ERRNO_SIGNAL;
529 }
530
531 if ((delay) && ((jiffies - j) >= delay)) {
532
533 PDEBUG("Timeout reached.\n");
534 err = ME_ERRNO_TIMEOUT;
535 }
536
537 *value =
538 (!err) ? instance->single_value_in_fifo : instance->
539 single_value;
540 } else { //Non-blocking mode
541 //Read value
542 *value = instance->single_value;
543 }
544
545 ME_SUBDEVICE_EXIT;
546
547 return err;
548}
549
550static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
551 struct file *filep,
552 int channel,
553 int value, int time_out, int flags)
554{
555 me4600_ao_subdevice_t *instance;
556 int err = ME_ERRNO_SUCCESS;
557 unsigned long cpu_flags;
558 unsigned long j;
559 unsigned long delay = 0x0;
560
561 //Registry handling variables.
562 uint32_t sync_mask;
563 uint32_t mode;
564 uint32_t tmp;
565 uint32_t ctrl;
566 uint32_t status;
567
568 instance = (me4600_ao_subdevice_t *) subdevice;
569
570 PDEBUG("executed. idx=%d\n", instance->ao_idx);
571
572 if (flags &
573 ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS |
574 ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
575 PERROR("Invalid flag specified.\n");
576 return ME_ERRNO_INVALID_FLAGS;
577 }
578
579 if (time_out < 0) {
580 PERROR("Invalid timeout specified.\n");
581 return ME_ERRNO_INVALID_TIMEOUT;
582 }
583
584 if (value & ~ME4600_AO_MAX_DATA) {
585 PERROR("Invalid value provided.\n");
586 return ME_ERRNO_VALUE_OUT_OF_RANGE;
587 }
588
589 if (channel != 0) {
590 PERROR("Invalid channel number specified.\n");
591 return ME_ERRNO_INVALID_CHANNEL;
592 }
593
594 if ((instance->status == ao_status_none)
595 || (instance->status > ao_status_single_end)) {
596 PERROR("Subdevice not configured to work in single mode!\n");
597 return ME_ERRNO_PREVIOUS_CONFIG;
598 }
599
600 ME_SUBDEVICE_ENTER;
601
602/// @note For single all calls (config and write) are erasing previous state!
603
604 //Cancel control task
605 PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
606 instance->ao_control_task_flag = 0;
607 cancel_delayed_work(&instance->ao_control_task);
608
609 // Correct single mirrors
610 instance->single_value_in_fifo = instance->single_value;
611
612 //Stop device
613 err = ao_stop_immediately(instance);
614 if (err) {
615 PERROR_CRITICAL("FSM IS BUSY!\n");
616 ME_SUBDEVICE_EXIT;
617
618 return ME_ERRNO_SUBDEVICE_BUSY;
619 }
620
621 if (time_out) {
622 delay = (time_out * HZ) / 1000;
623
624 if (delay == 0)
625 delay = 1;
626 }
627
628 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
629
630 instance->single_value_in_fifo = value;
631
632 ctrl = inl(instance->ctrl_reg);
633
634 if (!instance->fifo) { //No FIFO
635 //Set the single mode.
636 ctrl &= ~ME4600_AO_CTRL_MODE_MASK;
637
638 //Write value
639 PDEBUG("Write value\n");
640 outl(value, instance->single_reg);
641 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
642 instance->reg_base,
643 instance->single_reg - instance->reg_base, value);
644 } else { // mix-mode
645 //Set speed
646 outl(ME4600_AO_MIN_CHAN_TICKS - 1, instance->timer_reg);
647 PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%x\n",
648 instance->reg_base,
649 instance->timer_reg - instance->reg_base,
650 (int)ME4600_AO_MIN_CHAN_TICKS);
651 instance->hardware_stop_delay = HZ / 10; //100ms
652
653 status = inl(instance->status_reg);
654
655 //Set the continous mode.
656 ctrl &= ~ME4600_AO_CTRL_MODE_MASK;
657 ctrl |= ME4600_AO_MODE_CONTINUOUS;
658
659 //Prepare FIFO
660 if (!(ctrl & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO wasn't enabeled. Do it.
661 PINFO("Enableing FIFO.\n");
662 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
663 ctrl |=
664 ME4600_AO_CTRL_BIT_ENABLE_FIFO |
665 ME4600_AO_CTRL_BIT_RESET_IRQ;
666 } else { //Check if FIFO is empty
667 if (status & ME4600_AO_STATUS_BIT_EF) { //FIFO not empty
668 PINFO("Reseting FIFO.\n");
669 ctrl &=
670 ~(ME4600_AO_CTRL_BIT_ENABLE_FIFO |
671 ME4600_AO_CTRL_BIT_ENABLE_IRQ);
672 ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
673 outl(ctrl, instance->ctrl_reg);
674 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
675 instance->reg_base,
676 instance->ctrl_reg -
677 instance->reg_base, ctrl);
678
679 ctrl |=
680 ME4600_AO_CTRL_BIT_ENABLE_FIFO |
681 ME4600_AO_CTRL_BIT_RESET_IRQ;
682 } else { //FIFO empty, only interrupt needs to be disabled!
683 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
684 ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
685 }
686 }
687
688 outl(ctrl, instance->ctrl_reg);
689 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
690 instance->reg_base,
691 instance->ctrl_reg - instance->reg_base, ctrl);
692
693 //Write output - 1 value to FIFO
694 if (instance->ao_idx & 0x1) {
695 outl(value <<= 16, instance->fifo_reg);
696 PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
697 instance->reg_base,
698 instance->fifo_reg - instance->reg_base,
699 value <<= 16);
700 } else {
701 outl(value, instance->fifo_reg);
702 PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
703 instance->reg_base,
704 instance->fifo_reg - instance->reg_base,
705 value);
706 }
707 }
708
709 mode = *instance->preload_flags >> instance->ao_idx;
710 mode &= (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG);
711
712 PINFO("Triggering mode: 0x%x\n", mode);
713
714 spin_lock(instance->preload_reg_lock);
715 sync_mask = inl(instance->preload_reg);
716 PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
717 instance->preload_reg - instance->reg_base, sync_mask);
718 switch (mode) {
719 case 0: //Individual software
720 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
721
722 if (!instance->fifo) { // No FIFO - In this case resetting 'ME4600_AO_SYNC_HOLD' will trigger output.
723 if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME4600_AO_SYNC_HOLD) { //Now we can set correct mode. This is exception. It is set to synchronous and triggered later.
724 sync_mask &=
725 ~(ME4600_AO_SYNC_EXT_TRIG << instance->
726 ao_idx);
727 sync_mask |=
728 ME4600_AO_SYNC_HOLD << instance->ao_idx;
729
730 outl(sync_mask, instance->preload_reg);
731 PDEBUG_REG
732 ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
733 instance->reg_base,
734 instance->preload_reg - instance->reg_base,
735 sync_mask);
736 }
737 } else { // FIFO
738 if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode.
739 sync_mask &=
740 ~((ME4600_AO_SYNC_EXT_TRIG |
741 ME4600_AO_SYNC_HOLD) << instance->
742 ao_idx);
743
744 outl(sync_mask, instance->preload_reg);
745 PDEBUG_REG
746 ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
747 instance->reg_base,
748 instance->preload_reg - instance->reg_base,
749 sync_mask);
750 }
751 }
752 instance->single_value = value;
753 break;
754
755 case ME4600_AO_SYNC_EXT_TRIG: //Individual hardware
756 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
757
758 if (!instance->fifo) { // No FIFO - In this case resetting 'ME4600_AO_SYNC_HOLD' will trigger output.
759 if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME4600_AO_SYNC_HOLD) { //Now we can set correct mode
760 sync_mask &=
761 ~(ME4600_AO_SYNC_EXT_TRIG << instance->
762 ao_idx);
763 sync_mask |=
764 ME4600_AO_SYNC_HOLD << instance->ao_idx;
765
766 outl(sync_mask, instance->preload_reg);
767 PDEBUG_REG
768 ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
769 instance->reg_base,
770 instance->preload_reg - instance->reg_base,
771 sync_mask);
772 }
773 } else { // FIFO
774 if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode.
775 sync_mask &=
776 ~((ME4600_AO_SYNC_EXT_TRIG |
777 ME4600_AO_SYNC_HOLD) << instance->
778 ao_idx);
779
780 outl(sync_mask, instance->preload_reg);
781 PDEBUG_REG
782 ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
783 instance->reg_base,
784 instance->preload_reg - instance->reg_base,
785 sync_mask);
786 }
787 }
788 break;
789
790 case ME4600_AO_SYNC_HOLD: //Synchronous software
791 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
792
793// if((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME4600_AO_SYNC_HOLD)
794 if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG)) { //Now we can set correct mode
795 sync_mask |=
796 ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx;
797// sync_mask &= ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx);
798 sync_mask |= ME4600_AO_SYNC_HOLD << instance->ao_idx;
799
800 outl(sync_mask, instance->preload_reg);
801 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
802 instance->reg_base,
803 instance->preload_reg - instance->reg_base,
804 sync_mask);
805 }
806 break;
807
808 case (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG): //Synchronous hardware
809 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
810 if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG)) { //Now we can set correct mode
811 sync_mask |=
812 (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) <<
813 instance->ao_idx;
814
815 outl(sync_mask, instance->preload_reg);
816 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
817 instance->reg_base,
818 instance->preload_reg - instance->reg_base,
819 sync_mask);
820 }
821 break;
822 }
823// spin_unlock(instance->preload_reg_lock); // Moved down.
824
825 //Activate ISM (remove 'stop' bits)
826 ctrl &=
827 ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
828 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
829 ctrl |= instance->ctrl_trg;
830 ctrl &= ~(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
831 outl(ctrl, instance->ctrl_reg);
832 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
833 instance->ctrl_reg - instance->reg_base, ctrl);
834 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
835
836/// @note When flag 'ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS' is set than output is triggered. ALWAYS!
837
838 if (!instance->fifo) { //No FIFO
839 if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Fired all software synchronous outputs.
840 tmp = ~(*instance->preload_flags | 0xFFFF0000);
841 PINFO
842 ("Fired all software synchronous outputs. mask:0x%08x\n",
843 tmp);
844 tmp |= sync_mask & 0xFFFF0000;
845 // Add this channel to list
846 tmp &= ~(ME4600_AO_SYNC_HOLD << instance->ao_idx);
847
848 //Fire
849 PINFO("Software trigger.\n");
850 outl(tmp, instance->preload_reg);
851 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
852 instance->reg_base,
853 instance->preload_reg - instance->reg_base,
854 tmp);
855
856 //Restore save settings
857 outl(sync_mask, instance->preload_reg);
858 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
859 instance->reg_base,
860 instance->preload_reg - instance->reg_base,
861 sync_mask);
862 } else if (!mode) { // Add this channel to list
863 outl(sync_mask &
864 ~(ME4600_AO_SYNC_HOLD << instance->ao_idx),
865 instance->preload_reg);
866 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
867 instance->reg_base,
868 instance->preload_reg - instance->reg_base,
869 sync_mask & ~(ME4600_AO_SYNC_HOLD <<
870 instance->ao_idx));
871
872 //Fire
873 PINFO("Software trigger.\n");
874
875 //Restore save settings
876 outl(sync_mask, instance->preload_reg);
877 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
878 instance->reg_base,
879 instance->preload_reg - instance->reg_base,
880 sync_mask);
881 }
882
883 } else { // mix-mode - begin
884 if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs
885 //Add channel to start list
886 outl(sync_mask |
887 (ME4600_AO_SYNC_HOLD << instance->ao_idx),
888 instance->preload_reg);
889 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
890 instance->reg_base,
891 instance->preload_reg - instance->reg_base,
892 sync_mask | (ME4600_AO_SYNC_HOLD <<
893 instance->ao_idx));
894
895 //Fire
896 PINFO
897 ("Fired all software synchronous outputs by software trigger.\n");
898 outl(0x8000, instance->single_reg);
899 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
900 instance->reg_base,
901 instance->single_reg - instance->reg_base,
902 0x8000);
903
904 //Restore save settings
905 outl(sync_mask, instance->preload_reg);
906 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
907 instance->reg_base,
908 instance->preload_reg - instance->reg_base,
909 sync_mask);
910 } else if (!mode) { //Trigger outputs
911/* //Remove channel from start list //<== Unnecessary. Removed.
912 outl(sync_mask & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
913 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, tmp);
914*/
915 //Fire
916 PINFO("Software trigger.\n");
917 outl(0x8000, instance->single_reg);
918 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
919 instance->reg_base,
920 instance->single_reg - instance->reg_base,
921 0x8000);
922
923/* //Restore save settings //<== Unnecessary. Removed.
924 outl(sync_mask, instance->preload_reg);
925 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask);
926*/
927 }
928 }
929 spin_unlock(instance->preload_reg_lock);
930
931 j = jiffies;
932 instance->status = ao_status_single_run_wait;
933
934 instance->timeout.delay = delay;
935 instance->timeout.start_time = j;
936 instance->ao_control_task_flag = 1;
937 queue_delayed_work(instance->me4600_workqueue,
938 &instance->ao_control_task, 1);
939
940 if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
941
942 //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
943 wait_event_interruptible_timeout(instance->wait_queue,
944 (instance->status !=
945 ao_status_single_run_wait),
946 (delay) ? delay +
947 1 : LONG_MAX);
948
949 if (((!delay) || ((jiffies - j) <= delay))
950 && (instance->status != ao_status_single_end)) {
951 PDEBUG("Single canceled.\n");
952 err = ME_ERRNO_CANCELLED;
953 }
954
955 if (signal_pending(current)) {
956 PERROR("Wait on start of state machine interrupted.\n");
957 instance->ao_control_task_flag = 0;
958 cancel_delayed_work(&instance->ao_control_task);
959 ao_stop_immediately(instance);
960 instance->status = ao_status_none;
961 err = ME_ERRNO_SIGNAL;
962 }
963
964 if ((delay) && ((jiffies - j) >= delay)) {
965 if (instance->status == ao_status_single_end) {
966 PDEBUG("Timeout reached.\n");
967 } else {
968 if ((jiffies - j) > delay) {
969 PERROR
970 ("Timeout reached. Not handled by control task!\n");
971 } else {
972 PERROR
973 ("Timeout reached. Signal come but status is strange: %d\n",
974 instance->status);
975 }
976
977 ao_stop_immediately(instance);
978 }
979
980 instance->ao_control_task_flag = 0;
981 cancel_delayed_work(&instance->ao_control_task);
982 instance->status = ao_status_single_end;
983 err = ME_ERRNO_TIMEOUT;
984 }
985 }
986
987 ME_SUBDEVICE_EXIT;
988
989 return err;
990}
991
992static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
993 struct file *filep,
994 meIOStreamConfig_t * config_list,
995 int count,
996 meIOStreamTrigger_t * trigger,
997 int fifo_irq_threshold, int flags)
998{
999 me4600_ao_subdevice_t *instance;
1000 int err = ME_ERRNO_SUCCESS;
1001 uint32_t ctrl;
1002 unsigned long cpu_flags;
1003 uint64_t conv_ticks;
1004 unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
1005 unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
1006
1007 instance = (me4600_ao_subdevice_t *) subdevice;
1008
1009 PDEBUG("executed. idx=%d\n", instance->ao_idx);
1010
1011 if (!instance->fifo) {
1012 PERROR("Not a streaming ao.\n");
1013 return ME_ERRNO_NOT_SUPPORTED;
1014 }
1015
1016 conv_ticks =
1017 (uint64_t) conv_start_ticks_low +
1018 ((uint64_t) conv_start_ticks_high << 32);
1019
1020 if (flags &
1021 ~(ME_IO_STREAM_CONFIG_HARDWARE_ONLY | ME_IO_STREAM_CONFIG_WRAPAROUND
1022 | ME_IO_STREAM_CONFIG_BIT_PATTERN)) {
1023 PERROR("Invalid flags.\n");
1024 return ME_ERRNO_INVALID_FLAGS;
1025 }
1026
1027 if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
1028 if (!flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
1029 PERROR
1030 ("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n");
1031 return ME_ERRNO_INVALID_FLAGS;
1032 }
1033
1034 if ((trigger->iAcqStopTrigType != ME_TRIG_TYPE_NONE)
1035 || (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE)) {
1036 PERROR
1037 ("Hardware wraparound mode must be in infinite mode.\n");
1038 return ME_ERRNO_INVALID_FLAGS;
1039 }
1040 }
1041
1042 if (count != 1) {
1043 PERROR("Only 1 entry in config list acceptable.\n");
1044 return ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
1045 }
1046
1047 if (config_list[0].iChannel != 0) {
1048 PERROR("Invalid channel number specified.\n");
1049 return ME_ERRNO_INVALID_CHANNEL;
1050 }
1051
1052 if (config_list[0].iStreamConfig != 0) {
1053 PERROR("Only one range available.\n");
1054 return ME_ERRNO_INVALID_STREAM_CONFIG;
1055 }
1056
1057 if (config_list[0].iRef != ME_REF_AO_GROUND) {
1058 PERROR("Output is referenced to ground.\n");
1059 return ME_ERRNO_INVALID_REF;
1060 }
1061
1062 if ((trigger->iAcqStartTicksLow != 0)
1063 || (trigger->iAcqStartTicksHigh != 0)) {
1064 PERROR
1065 ("Invalid acquisition start trigger argument specified.\n");
1066 return ME_ERRNO_INVALID_ACQ_START_ARG;
1067 }
1068
1069 if (config_list[0].iFlags) {
1070 PERROR("Invalid config list flag.\n");
1071 return ME_ERRNO_INVALID_FLAGS;
1072 }
1073
1074 switch (trigger->iAcqStartTrigType) {
1075 case ME_TRIG_TYPE_SW:
1076 if (trigger->iAcqStartTrigEdge != ME_TRIG_EDGE_NONE) {
1077 PERROR
1078 ("Invalid acquisition start trigger edge specified.\n");
1079 return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
1080 }
1081 break;
1082
1083 case ME_TRIG_TYPE_EXT_DIGITAL:
1084 switch (trigger->iAcqStartTrigEdge) {
1085 case ME_TRIG_EDGE_ANY:
1086 case ME_TRIG_EDGE_RISING:
1087 case ME_TRIG_EDGE_FALLING:
1088 break;
1089
1090 default:
1091 PERROR
1092 ("Invalid acquisition start trigger edge specified.\n");
1093 return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
1094 }
1095 break;
1096
1097 default:
1098 PERROR("Invalid acquisition start trigger type specified.\n");
1099 return ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
1100 }
1101
1102 if (trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW) {
1103 PERROR("Invalid scan start trigger type specified.\n");
1104 return ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
1105 }
1106
1107 if (trigger->iConvStartTrigType != ME_TRIG_TYPE_TIMER) {
1108 PERROR("Invalid conv start trigger type specified.\n");
1109 return ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
1110 }
1111
1112 if ((conv_ticks < ME4600_AO_MIN_CHAN_TICKS)
1113 || (conv_ticks > ME4600_AO_MAX_CHAN_TICKS)) {
1114 PERROR("Invalid conv start trigger argument specified.\n");
1115 return ME_ERRNO_INVALID_CONV_START_ARG;
1116 }
1117
1118 if (trigger->iAcqStartTicksLow || trigger->iAcqStartTicksHigh) {
1119 PERROR("Invalid acq start trigger argument specified.\n");
1120 return ME_ERRNO_INVALID_ACQ_START_ARG;
1121 }
1122
1123 if (trigger->iScanStartTicksLow || trigger->iScanStartTicksHigh) {
1124 PERROR("Invalid scan start trigger argument specified.\n");
1125 return ME_ERRNO_INVALID_SCAN_START_ARG;
1126 }
1127
1128 switch (trigger->iScanStopTrigType) {
1129 case ME_TRIG_TYPE_NONE:
1130 if (trigger->iScanStopCount != 0) {
1131 PERROR("Invalid scan stop count specified.\n");
1132 return ME_ERRNO_INVALID_SCAN_STOP_ARG;
1133 }
1134 break;
1135
1136 case ME_TRIG_TYPE_COUNT:
1137 if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
1138 if (trigger->iScanStopCount <= 0) {
1139 PERROR("Invalid scan stop count specified.\n");
1140 return ME_ERRNO_INVALID_SCAN_STOP_ARG;
1141 }
1142 } else {
1143 PERROR("The continous mode has not 'scan' contects.\n");
1144 return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1145 }
1146 break;
1147
1148 default:
1149 PERROR("Invalid scan stop trigger type specified.\n");
1150 return ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
1151 }
1152
1153 switch (trigger->iAcqStopTrigType) {
1154 case ME_TRIG_TYPE_NONE:
1155 if (trigger->iAcqStopCount != 0) {
1156 PERROR("Invalid acq stop count specified.\n");
1157 return ME_ERRNO_INVALID_ACQ_STOP_ARG;
1158 }
1159 break;
1160
1161 case ME_TRIG_TYPE_COUNT:
1162 if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
1163 PERROR("Invalid acq stop trigger type specified.\n");
1164 return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1165 }
1166
1167 if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
1168 if (trigger->iAcqStopCount <= 0) {
1169 PERROR
1170 ("The continous mode has not 'scan' contects.\n");
1171 return ME_ERRNO_INVALID_ACQ_STOP_ARG;
1172 }
1173 }
1174 break;
1175
1176 default:
1177 PERROR("Invalid acq stop trigger type specified.\n");
1178 return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1179 }
1180
1181 switch (trigger->iAcqStartTrigChan) {
1182 case ME_TRIG_CHAN_DEFAULT:
1183 case ME_TRIG_CHAN_SYNCHRONOUS:
1184 break;
1185
1186 default:
1187 PERROR("Invalid acq start trigger channel specified.\n");
1188 return ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
1189 }
1190
1191 ME_SUBDEVICE_ENTER;
1192
1193 if ((flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) && !instance->bitpattern) {
1194 PERROR("This subdevice not support output redirection.\n");
1195 ME_SUBDEVICE_EXIT;
1196 return ME_ERRNO_INVALID_FLAGS;
1197 }
1198 //Stop device
1199
1200 //Cancel control task
1201 PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
1202 instance->ao_control_task_flag = 0;
1203 cancel_delayed_work(&instance->ao_control_task);
1204
1205 //Check if state machine is stopped.
1206 err = ao_stop_immediately(instance);
1207 if (err) {
1208 PERROR_CRITICAL("FSM IS BUSY!\n");
1209 ME_SUBDEVICE_EXIT;
1210
1211 return ME_ERRNO_SUBDEVICE_BUSY;
1212 }
1213
1214 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
1215 //Reset control register. Block all actions. Disable IRQ. Disable FIFO.
1216 ctrl =
1217 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP |
1218 ME4600_AO_CTRL_BIT_RESET_IRQ;
1219 outl(ctrl, instance->ctrl_reg);
1220 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1221 instance->ctrl_reg - instance->reg_base, ctrl);
1222
1223 //This is paranoic, but to be sure.
1224 instance->preloaded_count = 0;
1225 instance->data_count = 0;
1226 instance->circ_buf.head = 0;
1227 instance->circ_buf.tail = 0;
1228
1229 /* Set mode. */
1230 if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { //Wraparound
1231 if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) { //Hardware wraparound
1232 PINFO("Hardware wraparound.\n");
1233 ctrl |= ME4600_AO_MODE_WRAPAROUND;
1234 instance->mode = ME4600_AO_HW_WRAP_MODE;
1235 } else { //Software wraparound
1236 PINFO("Software wraparound.\n");
1237 ctrl |= ME4600_AO_MODE_CONTINUOUS;
1238 instance->mode = ME4600_AO_SW_WRAP_MODE;
1239 }
1240 } else { //Continous
1241 PINFO("Continous.\n");
1242 ctrl |= ME4600_AO_MODE_CONTINUOUS;
1243 instance->mode = ME4600_AO_CONTINOUS;
1244 }
1245
1246 //Set the trigger edge.
1247 if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Set the trigger type and edge for external trigger.
1248 PINFO("External digital trigger.\n");
1249 instance->start_mode = ME4600_AO_EXT_TRIG;
1250/*
1251 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
1252*/
1253 switch (trigger->iAcqStartTrigEdge) {
1254 case ME_TRIG_EDGE_RISING:
1255 PINFO("Set the trigger edge: rising.\n");
1256 instance->ctrl_trg = 0x0;
1257 break;
1258
1259 case ME_TRIG_EDGE_FALLING:
1260 PINFO("Set the trigger edge: falling.\n");
1261// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
1262 instance->ctrl_trg = ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
1263 break;
1264
1265 case ME_TRIG_EDGE_ANY:
1266 PINFO("Set the trigger edge: both edges.\n");
1267// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
1268 instance->ctrl_trg =
1269 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
1270 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
1271 break;
1272 }
1273 } else {
1274 PINFO("Internal software trigger.\n");
1275 instance->start_mode = 0;
1276 }
1277
1278 //Set the stop mode and value.
1279 if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of data
1280 instance->stop_mode = ME4600_AO_ACQ_STOP_MODE;
1281 instance->stop_count = trigger->iAcqStopCount;
1282 } else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of 'scans'
1283 instance->stop_mode = ME4600_AO_SCAN_STOP_MODE;
1284 instance->stop_count = trigger->iScanStopCount;
1285 } else { //Infinite
1286 instance->stop_mode = ME4600_AO_INF_STOP_MODE;
1287 instance->stop_count = 0;
1288 }
1289
1290 PINFO("Stop count: %d.\n", instance->stop_count);
1291
1292 if (trigger->iAcqStartTrigChan == ME_TRIG_CHAN_SYNCHRONOUS) { //Synchronous start
1293 instance->start_mode |= ME4600_AO_SYNC_HOLD;
1294 if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Externaly triggered
1295 PINFO("Synchronous start. Externaly trigger active.\n");
1296 instance->start_mode |= ME4600_AO_SYNC_EXT_TRIG;
1297 }
1298#ifdef MEDEBUG_INFO
1299 else {
1300 PINFO
1301 ("Synchronous start. Externaly trigger dissabled.\n");
1302 }
1303#endif
1304
1305 }
1306 //Set speed
1307 outl(conv_ticks - 2, instance->timer_reg);
1308 PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%llx\n", instance->reg_base,
1309 instance->timer_reg - instance->reg_base, conv_ticks - 2);
1310 instance->hardware_stop_delay = (int)(conv_ticks * HZ) / ME4600_AO_BASE_FREQUENCY; //<== MUST be with cast!
1311
1312 //Conect outputs to analog or digital port.
1313 if (flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) {
1314 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_DO;
1315 }
1316 // Write the control word
1317 outl(ctrl, instance->ctrl_reg);
1318 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1319 instance->ctrl_reg - instance->reg_base, ctrl);
1320
1321 //Set status.
1322 instance->status = ao_status_stream_configured;
1323 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
1324
1325 ME_SUBDEVICE_EXIT;
1326
1327 return err;
1328}
1329
1330static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
1331 struct file *filep,
1332 int time_out, int *count, int flags)
1333{
1334 me4600_ao_subdevice_t *instance;
1335 int err = ME_ERRNO_SUCCESS;
1336 long t = 0;
1337 long j;
1338
1339 instance = (me4600_ao_subdevice_t *) subdevice;
1340
1341 PDEBUG("executed. idx=%d\n", instance->ao_idx);
1342
1343 if (!instance->fifo) {
1344 PERROR("Not a streaming ao.\n");
1345 return ME_ERRNO_NOT_SUPPORTED;
1346 }
1347
1348 if (flags) {
1349 PERROR("Invalid flag specified.\n");
1350 return ME_ERRNO_INVALID_FLAGS;
1351 }
1352
1353 if (!instance->circ_buf.buf) {
1354 PERROR("Circular buffer not exists.\n");
1355 return ME_ERRNO_INTERNAL;
1356 }
1357
1358 if (time_out < 0) {
1359 PERROR("Invalid time_out specified.\n");
1360 return ME_ERRNO_INVALID_TIMEOUT;
1361 }
1362
1363 ME_SUBDEVICE_ENTER;
1364
1365 if (me_circ_buf_space(&instance->circ_buf)) { //The buffer is NOT full.
1366 *count = me_circ_buf_space(&instance->circ_buf);
1367 } else { //The buffer is full.
1368 if (time_out) {
1369 t = (time_out * HZ) / 1000;
1370
1371 if (t == 0)
1372 t = 1;
1373 } else { //Max time.
1374 t = LONG_MAX;
1375 }
1376
1377 *count = 0;
1378
1379 j = jiffies;
1380
1381 //Only runing process will interrupt this call. Interrupts are when FIFO HF is signaled.
1382 wait_event_interruptible_timeout(instance->wait_queue,
1383 ((me_circ_buf_space
1384 (&instance->circ_buf))
1385 || !(inl(instance->status_reg)
1386 &
1387 ME4600_AO_STATUS_BIT_FSM)),
1388 t);
1389
1390 if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
1391 PERROR("AO subdevice is not running.\n");
1392 err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
1393 } else if (signal_pending(current)) {
1394 PERROR("Wait on values interrupted from signal.\n");
1395 instance->status = ao_status_none;
1396 ao_stop_immediately(instance);
1397 err = ME_ERRNO_SIGNAL;
1398 } else if ((jiffies - j) >= t) {
1399 PERROR("Wait on values timed out.\n");
1400 err = ME_ERRNO_TIMEOUT;
1401 } else { //Uff... all is good. Inform user about empty space.
1402 *count = me_circ_buf_space(&instance->circ_buf);
1403 }
1404 }
1405
1406 ME_SUBDEVICE_EXIT;
1407
1408 return err;
1409}
1410
1411static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
1412 struct file *filep,
1413 int start_mode, int time_out, int flags)
1414{
1415 me4600_ao_subdevice_t *instance;
1416 int err = ME_ERRNO_SUCCESS;
1417 unsigned long cpu_flags = 0;
1418 uint32_t status;
1419 uint32_t ctrl;
1420 uint32_t synch;
1421 int count = 0;
1422 int circ_buffer_count;
1423
1424 unsigned long ref;
1425 unsigned long delay = 0;
1426
1427 instance = (me4600_ao_subdevice_t *) subdevice;
1428
1429 PDEBUG("executed. idx=%d\n", instance->ao_idx);
1430
1431 if (!instance->fifo) {
1432 PERROR("Not a streaming ao.\n");
1433 return ME_ERRNO_NOT_SUPPORTED;
1434 }
1435
1436 if (flags & ~ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
1437 PERROR("Invalid flags.\n");
1438 return ME_ERRNO_INVALID_FLAGS;
1439 }
1440
1441 if (time_out < 0) {
1442 PERROR("Invalid timeout specified.\n");
1443 return ME_ERRNO_INVALID_TIMEOUT;
1444 }
1445
1446 if ((start_mode != ME_START_MODE_BLOCKING)
1447 && (start_mode != ME_START_MODE_NONBLOCKING)) {
1448 PERROR("Invalid start mode specified.\n");
1449 return ME_ERRNO_INVALID_START_MODE;
1450 }
1451
1452 if (time_out) {
1453 delay = (time_out * HZ) / 1000;
1454 if (delay == 0)
1455 delay = 1;
1456 }
1457
1458 switch (instance->status) { //Checking actual mode.
1459 case ao_status_stream_configured:
1460 case ao_status_stream_end:
1461 //Correct modes!
1462 break;
1463
1464 //The device is in wrong mode.
1465 case ao_status_none:
1466 case ao_status_single_configured:
1467 case ao_status_single_run_wait:
1468 case ao_status_single_run:
1469 case ao_status_single_end_wait:
1470 PERROR
1471 ("Subdevice must be preinitialize correctly for streaming.\n");
1472 return ME_ERRNO_PREVIOUS_CONFIG;
1473
1474 case ao_status_stream_fifo_error:
1475 case ao_status_stream_buffer_error:
1476 case ao_status_stream_error:
1477 PDEBUG("Before restart broke stream 'STOP' must be caled.\n");
1478 return ME_STATUS_ERROR;
1479
1480 case ao_status_stream_run_wait:
1481 case ao_status_stream_run:
1482 case ao_status_stream_end_wait:
1483 PDEBUG("Stream is already working.\n");
1484 return ME_ERRNO_SUBDEVICE_BUSY;
1485
1486 default:
1487 instance->status = ao_status_stream_error;
1488 PERROR_CRITICAL("Status is in wrong state!\n");
1489 return ME_ERRNO_INTERNAL;
1490
1491 }
1492
1493 ME_SUBDEVICE_ENTER;
1494
1495 if (instance->mode == ME4600_AO_CONTINOUS) { //Continous
1496 instance->circ_buf.tail += instance->preloaded_count;
1497 instance->circ_buf.tail &= instance->circ_buf.mask;
1498 }
1499 circ_buffer_count = me_circ_buf_values(&instance->circ_buf);
1500
1501 if (!circ_buffer_count && !instance->preloaded_count) { //No values in buffer
1502 ME_SUBDEVICE_EXIT;
1503 PERROR("No values in buffer!\n");
1504 return ME_ERRNO_LACK_OF_RESOURCES;
1505 }
1506
1507 //Cancel control task
1508 PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
1509 instance->ao_control_task_flag = 0;
1510 cancel_delayed_work(&instance->ao_control_task);
1511
1512 //Stop device
1513 err = ao_stop_immediately(instance);
1514 if (err) {
1515 PERROR_CRITICAL("FSM IS BUSY!\n");
1516 ME_SUBDEVICE_EXIT;
1517
1518 return ME_ERRNO_SUBDEVICE_BUSY;
1519 }
1520 //Set values for single_read()
1521 instance->single_value = ME4600_AO_MAX_DATA + 1;
1522 instance->single_value_in_fifo = ME4600_AO_MAX_DATA + 1;
1523
1524 //Setting stop points
1525 if (instance->stop_mode == ME4600_AO_SCAN_STOP_MODE) {
1526 instance->stop_data_count =
1527 instance->stop_count * circ_buffer_count;
1528 } else {
1529 instance->stop_data_count = instance->stop_count;
1530 }
1531
1532 if ((instance->stop_data_count != 0)
1533 && (instance->stop_data_count < circ_buffer_count)) {
1534 PERROR("More data in buffer than previously set limit!\n");
1535 }
1536
1537 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
1538 ctrl = inl(instance->ctrl_reg);
1539 //Check FIFO
1540 if (!(ctrl & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO wasn't enabeled. Do it. <= This should be done by user call with ME_WRITE_MODE_PRELOAD
1541 PINFO("Enableing FIFO.\n");
1542 ctrl |=
1543 ME4600_AO_CTRL_BIT_ENABLE_FIFO |
1544 ME4600_AO_CTRL_BIT_RESET_IRQ;
1545
1546 instance->preloaded_count = 0;
1547 instance->data_count = 0;
1548 } else { //Block IRQ
1549 ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
1550 }
1551 outl(ctrl, instance->ctrl_reg);
1552 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1553 instance->ctrl_reg - instance->reg_base,
1554 ctrl | ME4600_AO_CTRL_BIT_RESET_IRQ);
1555
1556 //Fill FIFO <= Generaly this should be done by user pre-load call but this is second place to do it.
1557 status = inl(instance->status_reg);
1558 if (!(status & ME4600_AO_STATUS_BIT_EF)) { //FIFO empty
1559 if (instance->stop_data_count == 0) {
1560 count = ME4600_AO_FIFO_COUNT;
1561 } else {
1562 count =
1563 (ME4600_AO_FIFO_COUNT <
1564 instance->
1565 stop_data_count) ? ME4600_AO_FIFO_COUNT :
1566 instance->stop_data_count;
1567 }
1568
1569 //Copy data
1570 count =
1571 ao_write_data(instance, count, instance->preloaded_count);
1572
1573 if (count < 0) { //This should never happend!
1574 PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
1575 spin_unlock_irqrestore(&instance->subdevice_lock,
1576 cpu_flags);
1577 ME_SUBDEVICE_EXIT;
1578 return ME_ERRNO_INTERNAL;
1579 }
1580 }
1581 //Set pre-load features.
1582 spin_lock(instance->preload_reg_lock);
1583 synch = inl(instance->preload_reg);
1584 synch &=
1585 ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->
1586 ao_idx);
1587 synch |=
1588 (instance->start_mode & ~ME4600_AO_EXT_TRIG) << instance->ao_idx;
1589 outl(synch, instance->preload_reg);
1590 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1591 instance->preload_reg - instance->reg_base, synch);
1592 spin_unlock(instance->preload_reg_lock);
1593
1594 //Default count is '0'
1595 if (instance->mode == ME4600_AO_CONTINOUS) { //Continous
1596 instance->preloaded_count = 0;
1597 instance->circ_buf.tail += count;
1598 instance->circ_buf.tail &= instance->circ_buf.mask;
1599 } else { //Wraparound
1600 instance->preloaded_count += count;
1601 instance->data_count += count;
1602
1603 //Special case: Infinite wraparound with less than FIFO datas always should runs in hardware mode.
1604 if ((instance->stop_mode == ME4600_AO_INF_STOP_MODE)
1605 && (circ_buffer_count <= ME4600_AO_FIFO_COUNT)) { //Change to hardware wraparound
1606 PDEBUG
1607 ("Changeing mode from software wraparound to hardware wraparound.\n");
1608 //Copy all data
1609 count =
1610 ao_write_data(instance, circ_buffer_count,
1611 instance->preloaded_count);
1612 ctrl &= ~ME4600_AO_CTRL_MODE_MASK;
1613 ctrl |= ME4600_AO_MODE_WRAPAROUND;
1614 }
1615
1616 if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator.
1617 instance->preloaded_count = 0;
1618 } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend!
1619 PERROR_CRITICAL
1620 ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
1621 spin_unlock_irqrestore(&instance->subdevice_lock,
1622 cpu_flags);
1623 ME_SUBDEVICE_EXIT;
1624 return ME_ERRNO_INTERNAL;
1625 }
1626 }
1627
1628 //Set status to 'wait for start'
1629 instance->status = ao_status_stream_run_wait;
1630
1631 status = inl(instance->status_reg);
1632 //Start state machine and interrupts
1633 ctrl &= ~(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
1634 if (instance->start_mode == ME4600_AO_EXT_TRIG) { // External trigger.
1635 PINFO("External trigger.\n");
1636 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
1637 }
1638 if (!(status & ME4600_AO_STATUS_BIT_HF)) { //More than half!
1639 if ((ctrl & ME4600_AO_CTRL_MODE_MASK) == ME4600_AO_MODE_CONTINUOUS) { //Enable IRQ only when hardware_continous is set and FIFO is more than half
1640 ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
1641 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
1642 }
1643 }
1644 outl(ctrl, instance->ctrl_reg);
1645 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1646 instance->ctrl_reg - instance->reg_base, ctrl);
1647 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
1648
1649 //Trigger output
1650 if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs
1651 spin_lock(instance->preload_reg_lock);
1652 synch = inl(instance->preload_reg);
1653 //Add channel to start list
1654 outl(synch | (ME4600_AO_SYNC_HOLD << instance->ao_idx),
1655 instance->preload_reg);
1656 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
1657 instance->reg_base,
1658 instance->preload_reg - instance->reg_base,
1659 synch | (ME4600_AO_SYNC_HOLD << instance->ao_idx));
1660
1661 //Fire
1662 PINFO
1663 ("Fired all software synchronous outputs by software trigger.\n");
1664 outl(0x8000, instance->single_reg);
1665 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
1666 instance->reg_base,
1667 instance->single_reg - instance->reg_base, 0x8000);
1668
1669 //Restore save settings
1670 outl(synch, instance->preload_reg);
1671 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
1672 instance->reg_base,
1673 instance->preload_reg - instance->reg_base, synch);
1674 spin_unlock(instance->preload_reg_lock);
1675 } else if (!instance->start_mode) { //Trigger outputs
1676/*
1677 //Remove channel from start list. // <== Unnecessary. Removed.
1678 spin_lock(instance->preload_reg_lock);
1679 synch = inl(instance->preload_reg);
1680 outl(synch & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
1681 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx));
1682*/
1683 //Fire
1684 PINFO("Software trigger.\n");
1685 outl(0x8000, instance->single_reg);
1686 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
1687 instance->reg_base,
1688 instance->single_reg - instance->reg_base, 0x8000);
1689
1690/*
1691 //Restore save settings. // <== Unnecessary. Removed.
1692 outl(synch, instance->preload_reg);
1693 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch);
1694 spin_unlock(instance->preload_reg_lock);
1695*/
1696 }
1697 // Set control task's timeout
1698 ref = jiffies;
1699 instance->timeout.delay = delay;
1700 instance->timeout.start_time = ref;
1701
1702 if (status & ME4600_AO_STATUS_BIT_HF) { //Less than half but not empty!
1703 PINFO("Less than half.\n");
1704 if (instance->stop_data_count != 0) {
1705 count = ME4600_AO_FIFO_COUNT / 2;
1706 } else {
1707 count =
1708 ((ME4600_AO_FIFO_COUNT / 2) <
1709 instance->stop_data_count) ? ME4600_AO_FIFO_COUNT /
1710 2 : instance->stop_data_count;
1711 }
1712
1713 //Copy data
1714 count =
1715 ao_write_data(instance, count, instance->preloaded_count);
1716
1717 if (count < 0) { //This should never happend!
1718 PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
1719 ME_SUBDEVICE_EXIT;
1720 return ME_ERRNO_INTERNAL;
1721 }
1722
1723 if (instance->mode == ME4600_AO_CONTINOUS) { //Continous
1724 instance->circ_buf.tail += count;
1725 instance->circ_buf.tail &= instance->circ_buf.mask;
1726 } else { //Wraparound
1727 instance->data_count += count;
1728 instance->preloaded_count += count;
1729
1730 if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator.
1731 instance->preloaded_count = 0;
1732 } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend!
1733 PERROR_CRITICAL
1734 ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
1735 ME_SUBDEVICE_EXIT;
1736 return ME_ERRNO_INTERNAL;
1737 }
1738 }
1739
1740 status = inl(instance->status_reg);
1741 if (!(status & ME4600_AO_STATUS_BIT_HF)) { //More than half!
1742 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
1743 ctrl = inl(instance->ctrl_reg);
1744 ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
1745 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
1746 outl(ctrl, instance->ctrl_reg);
1747 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
1748 instance->reg_base,
1749 instance->ctrl_reg - instance->reg_base,
1750 ctrl);
1751 spin_unlock_irqrestore(&instance->subdevice_lock,
1752 cpu_flags);
1753 }
1754 }
1755 //Special case: Limited wraparound with less than HALF FIFO datas need work around to generate first interrupt.
1756 if ((instance->stop_mode != ME4600_AO_INF_STOP_MODE)
1757 && (instance->mode == ME4600_AO_SW_WRAP_MODE)
1758 && (circ_buffer_count <= (ME4600_AO_FIFO_COUNT / 2))) { //Put more data to FIFO
1759 PINFO("Limited wraparound with less than HALF FIFO datas.\n");
1760 if (instance->preloaded_count) { //This should never happend!
1761 PERROR_CRITICAL
1762 ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
1763 ME_SUBDEVICE_EXIT;
1764 return ME_ERRNO_INTERNAL;
1765 }
1766
1767 while (instance->stop_data_count > instance->data_count) { //Maximum data not set jet.
1768 //Copy to buffer
1769 if (circ_buffer_count != ao_write_data(instance, circ_buffer_count, 0)) { //This should never happend!
1770 PERROR_CRITICAL
1771 ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
1772 ME_SUBDEVICE_EXIT;
1773 return ME_ERRNO_INTERNAL;
1774 }
1775 instance->data_count += circ_buffer_count;
1776
1777 if (!((status = inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_HF)) { //FIFO is more than half. Enable IRQ and end copy.
1778 spin_lock_irqsave(&instance->subdevice_lock,
1779 cpu_flags);
1780 ctrl = inl(instance->ctrl_reg);
1781 ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
1782 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
1783 outl(ctrl, instance->ctrl_reg);
1784 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
1785 instance->reg_base,
1786 instance->ctrl_reg -
1787 instance->reg_base, ctrl);
1788 spin_unlock_irqrestore(&instance->
1789 subdevice_lock,
1790 cpu_flags);
1791 break;
1792 }
1793 }
1794 }
1795 // Schedule control task.
1796 instance->ao_control_task_flag = 1;
1797 queue_delayed_work(instance->me4600_workqueue,
1798 &instance->ao_control_task, 1);
1799
1800 if (start_mode == ME_START_MODE_BLOCKING) { //Wait for start.
1801 //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
1802 wait_event_interruptible_timeout(instance->wait_queue,
1803 (instance->status !=
1804 ao_status_stream_run_wait),
1805 (delay) ? delay +
1806 1 : LONG_MAX);
1807
1808 if ((instance->status != ao_status_stream_run)
1809 && (instance->status != ao_status_stream_end)) {
1810 PDEBUG("Starting stream canceled. %d\n",
1811 instance->status);
1812 err = ME_ERRNO_CANCELLED;
1813 }
1814
1815 if (signal_pending(current)) {
1816 PERROR("Wait on start of state machine interrupted.\n");
1817 instance->status = ao_status_none;
1818 ao_stop_immediately(instance);
1819 err = ME_ERRNO_SIGNAL;
1820 } else if ((delay) && ((jiffies - ref) >= delay)) {
1821 if (instance->status != ao_status_stream_run) {
1822 if (instance->status == ao_status_stream_end) {
1823 PDEBUG("Timeout reached.\n");
1824 } else {
1825 if ((jiffies - ref) > delay) {
1826 PERROR
1827 ("Timeout reached. Not handled by control task!\n");
1828 } else {
1829 PERROR
1830 ("Timeout reached. Signal come but status is strange: %d\n",
1831 instance->status);
1832 }
1833 ao_stop_immediately(instance);
1834 }
1835
1836 instance->ao_control_task_flag = 0;
1837 cancel_delayed_work(&instance->ao_control_task);
1838 instance->status = ao_status_stream_end;
1839 err = ME_ERRNO_TIMEOUT;
1840 }
1841 }
1842 }
1843
1844 ME_SUBDEVICE_EXIT;
1845 return err;
1846}
1847
1848static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
1849 struct file *filep,
1850 int wait,
1851 int *status, int *values, int flags)
1852{
1853 me4600_ao_subdevice_t *instance;
1854 int err = ME_ERRNO_SUCCESS;
1855
1856 instance = (me4600_ao_subdevice_t *) subdevice;
1857
1858 PDEBUG("executed. idx=%d\n", instance->ao_idx);
1859
1860 if (!instance->fifo) {
1861 PERROR("Not a streaming ao.\n");
1862 return ME_ERRNO_NOT_SUPPORTED;
1863 }
1864
1865 if (flags) {
1866 PERROR("Invalid flag specified.\n");
1867 return ME_ERRNO_INVALID_FLAGS;
1868 }
1869
1870 if ((wait != ME_WAIT_NONE) && (wait != ME_WAIT_IDLE)) {
1871 PERROR("Invalid wait argument specified.\n");
1872 *status = ME_STATUS_INVALID;
1873 return ME_ERRNO_INVALID_WAIT;
1874 }
1875
1876 ME_SUBDEVICE_ENTER;
1877
1878 switch (instance->status) {
1879 case ao_status_single_configured:
1880 case ao_status_single_end:
1881 case ao_status_stream_configured:
1882 case ao_status_stream_end:
1883 case ao_status_stream_fifo_error:
1884 case ao_status_stream_buffer_error:
1885 case ao_status_stream_error:
1886 *status = ME_STATUS_IDLE;
1887 break;
1888
1889 case ao_status_single_run_wait:
1890 case ao_status_single_run:
1891 case ao_status_single_end_wait:
1892 case ao_status_stream_run_wait:
1893 case ao_status_stream_run:
1894 case ao_status_stream_end_wait:
1895 *status = ME_STATUS_BUSY;
1896 break;
1897
1898 case ao_status_none:
1899 default:
1900 *status =
1901 (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ?
1902 ME_STATUS_BUSY : ME_STATUS_IDLE;
1903 break;
1904 }
1905
1906 if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) {
1907 //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
1908 wait_event_interruptible_timeout(instance->wait_queue,
1909 ((instance->status !=
1910 ao_status_single_run_wait)
1911 && (instance->status !=
1912 ao_status_single_run)
1913 && (instance->status !=
1914 ao_status_single_end_wait)
1915 && (instance->status !=
1916 ao_status_stream_run_wait)
1917 && (instance->status !=
1918 ao_status_stream_run)
1919 && (instance->status !=
1920 ao_status_stream_end_wait)),
1921 LONG_MAX);
1922
1923 if (instance->status != ao_status_stream_end) {
1924 PDEBUG("Wait for IDLE canceled. %d\n",
1925 instance->status);
1926 err = ME_ERRNO_CANCELLED;
1927 }
1928
1929 if (signal_pending(current)) {
1930 PERROR("Wait for IDLE interrupted.\n");
1931 instance->status = ao_status_none;
1932 ao_stop_immediately(instance);
1933 err = ME_ERRNO_SIGNAL;
1934 }
1935
1936 *status = ME_STATUS_IDLE;
1937 }
1938
1939 *values = me_circ_buf_space(&instance->circ_buf);
1940
1941 ME_SUBDEVICE_EXIT;
1942
1943 return err;
1944}
1945
1946static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
1947 struct file *filep,
1948 int stop_mode, int flags)
1949{ // Stop work and empty buffer and FIFO
1950 int err = ME_ERRNO_SUCCESS;
1951 me4600_ao_subdevice_t *instance;
1952 unsigned long cpu_flags;
1953 volatile uint32_t ctrl;
1954
1955 instance = (me4600_ao_subdevice_t *) subdevice;
1956
1957 PDEBUG("executed. idx=%d\n", instance->ao_idx);
1958
1959 if (flags & ~ME_IO_STREAM_STOP_PRESERVE_BUFFERS) {
1960 PERROR("Invalid flag specified.\n");
1961 return ME_ERRNO_INVALID_FLAGS;
1962 }
1963
1964 if ((stop_mode != ME_STOP_MODE_IMMEDIATE)
1965 && (stop_mode != ME_STOP_MODE_LAST_VALUE)) {
1966 PERROR("Invalid stop mode specified.\n");
1967 return ME_ERRNO_INVALID_STOP_MODE;
1968 }
1969
1970 if (!instance->fifo) {
1971 PERROR("Not a streaming ao.\n");
1972 return ME_ERRNO_NOT_SUPPORTED;
1973 }
1974
1975 if (instance->status < ao_status_stream_configured) {
1976 //There is nothing to stop!
1977 PERROR("Subdevice not in streaming mode. %d\n",
1978 instance->status);
1979 return ME_ERRNO_PREVIOUS_CONFIG;
1980 }
1981
1982 ME_SUBDEVICE_ENTER;
1983
1984 //Mark as stopping. => Software stop.
1985 instance->status = ao_status_stream_end_wait;
1986
1987 if (stop_mode == ME_STOP_MODE_IMMEDIATE) { //Stopped now!
1988 err = ao_stop_immediately(instance);
1989 } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
1990 ctrl = inl(instance->ctrl_reg) & ME4600_AO_CTRL_MODE_MASK;
1991 if (ctrl == ME4600_AO_MODE_WRAPAROUND) { //Hardware wraparound => Hardware stop.
1992 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
1993 ctrl = inl(instance->ctrl_reg);
1994 ctrl |=
1995 ME4600_AO_CTRL_BIT_STOP |
1996 ME4600_AO_CTRL_BIT_RESET_IRQ;
1997 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
1998 outl(ctrl, instance->ctrl_reg);
1999 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2000 instance->reg_base,
2001 instance->ctrl_reg - instance->reg_base,
2002 ctrl);
2003 spin_unlock_irqrestore(&instance->subdevice_lock,
2004 cpu_flags);
2005 }
2006 //Only runing process will interrupt this call. Events are signaled when status change.
2007 wait_event_interruptible_timeout(instance->wait_queue,
2008 (instance->status !=
2009 ao_status_stream_end_wait),
2010 LONG_MAX);
2011
2012 if (instance->status != ao_status_stream_end) {
2013 PDEBUG("Stopping stream canceled.\n");
2014 err = ME_ERRNO_CANCELLED;
2015 }
2016
2017 if (signal_pending(current)) {
2018 PERROR("Stopping stream interrupted.\n");
2019 instance->status = ao_status_none;
2020 ao_stop_immediately(instance);
2021 err = ME_ERRNO_SIGNAL;
2022 }
2023 }
2024
2025 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2026 ctrl = inl(instance->ctrl_reg);
2027 ctrl |=
2028 ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
2029 ME4600_AO_CTRL_BIT_RESET_IRQ;
2030 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
2031 if (!flags) { //Reset FIFO
2032 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO;
2033 }
2034 outl(ctrl, instance->ctrl_reg);
2035 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
2036 instance->ctrl_reg - instance->reg_base, ctrl);
2037 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
2038
2039 if (!flags) { //Reset software buffer
2040 instance->circ_buf.head = 0;
2041 instance->circ_buf.tail = 0;
2042 instance->preloaded_count = 0;
2043 instance->data_count = 0;
2044 }
2045
2046 ME_SUBDEVICE_EXIT;
2047
2048 return err;
2049}
2050
2051static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
2052 struct file *filep,
2053 int write_mode,
2054 int *values, int *count, int flags)
2055{
2056 int err = ME_ERRNO_SUCCESS;
2057 me4600_ao_subdevice_t *instance;
2058 unsigned long cpu_flags = 0;
2059 uint32_t reg_copy;
2060
2061 int copied_from_user = 0;
2062 int left_to_copy_from_user = *count;
2063
2064 int copied_values;
2065
2066 instance = (me4600_ao_subdevice_t *) subdevice;
2067
2068 PDEBUG("executed. idx=%d\n", instance->ao_idx);
2069
2070 //Checking arguments
2071 if (!instance->fifo) {
2072 PERROR("Not a streaming ao.\n");
2073 return ME_ERRNO_NOT_SUPPORTED;
2074 }
2075
2076 if (flags) {
2077 PERROR("Invalid flag specified.\n");
2078 return ME_ERRNO_INVALID_FLAGS;
2079 }
2080
2081 if (*count <= 0) {
2082 PERROR("Invalid count of values specified.\n");
2083 return ME_ERRNO_INVALID_VALUE_COUNT;
2084 }
2085
2086 if (values == NULL) {
2087 PERROR("Invalid address of values specified.\n");
2088 return ME_ERRNO_INVALID_POINTER;
2089 }
2090
2091 if ((instance->status == ao_status_none) || (instance->status == ao_status_single_configured)) { //The device is in single mode.
2092 PERROR
2093 ("Subdevice must be preinitialize correctly for streaming.\n");
2094 return ME_ERRNO_PREVIOUS_CONFIG;
2095 }
2096/// @note If no 'pre-load' is used. stream_start() will move data to FIFO.
2097 switch (write_mode) {
2098 case ME_WRITE_MODE_PRELOAD:
2099
2100 //Device must be stopped.
2101 if ((instance->status != ao_status_stream_configured)
2102 && (instance->status != ao_status_stream_end)) {
2103 PERROR
2104 ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
2105 return ME_ERRNO_PREVIOUS_CONFIG;
2106 }
2107 break;
2108 case ME_WRITE_MODE_NONBLOCKING:
2109 case ME_WRITE_MODE_BLOCKING:
2110 /// @note In blocking mode: When device is not runing and there is not enought space call will blocked up!
2111 /// @note Some other thread must empty buffer by starting engine.
2112 break;
2113
2114 default:
2115 PERROR("Invalid write mode specified.\n");
2116 return ME_ERRNO_INVALID_WRITE_MODE;
2117 }
2118
2119 if (instance->mode & ME4600_AO_WRAP_MODE) { //Wraparound mode. Device must be stopped.
2120 if ((instance->status != ao_status_stream_configured)
2121 && (instance->status != ao_status_stream_end)) {
2122 PERROR
2123 ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
2124 return ME_ERRNO_INVALID_WRITE_MODE;
2125 }
2126 }
2127
2128 if ((instance->mode == ME4600_AO_HW_WRAP_MODE) && (write_mode != ME_WRITE_MODE_PRELOAD)) { // hardware wrap_around mode.
2129 //This is transparent for user.
2130 PDEBUG("Changing write_mode to ME_WRITE_MODE_PRELOAD.\n");
2131 write_mode = ME_WRITE_MODE_PRELOAD;
2132 }
2133
2134 ME_SUBDEVICE_ENTER;
2135
2136 if (write_mode == ME_WRITE_MODE_PRELOAD) { //Init enviroment - preload
2137 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2138 reg_copy = inl(instance->ctrl_reg);
2139 //Check FIFO
2140 if (!(reg_copy & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO not active. Enable it.
2141 reg_copy |= ME4600_AO_CTRL_BIT_ENABLE_FIFO;
2142 outl(reg_copy, instance->ctrl_reg);
2143 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2144 instance->reg_base,
2145 instance->ctrl_reg - instance->reg_base,
2146 reg_copy);
2147 instance->preloaded_count = 0;
2148 }
2149 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
2150 }
2151
2152 while (1) {
2153 //Copy to buffer. This step is common for all modes.
2154 copied_from_user =
2155 ao_get_data_from_user(instance, left_to_copy_from_user,
2156 values + (*count -
2157 left_to_copy_from_user));
2158 left_to_copy_from_user -= copied_from_user;
2159
2160 reg_copy = inl(instance->status_reg);
2161 if ((instance->status == ao_status_stream_run) && !(reg_copy & ME4600_AO_STATUS_BIT_FSM)) { //BROKEN PIPE! The state machine is stoped but logical status show that should be working.
2162 PERROR("Broken pipe in write.\n");
2163 err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
2164 break;
2165 }
2166
2167 if ((instance->status == ao_status_stream_run) && (instance->mode == ME4600_AO_CONTINOUS) && (reg_copy & ME4600_AO_STATUS_BIT_HF)) { //Continous mode runing and data are below half!
2168
2169 // Block interrupts.
2170 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2171 reg_copy = inl(instance->ctrl_reg);
2172 //reg_copy &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
2173 reg_copy |= ME4600_AO_CTRL_BIT_RESET_IRQ;
2174 outl(reg_copy, instance->ctrl_reg);
2175 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2176 instance->reg_base,
2177 instance->ctrl_reg - instance->reg_base,
2178 reg_copy);
2179 spin_unlock_irqrestore(&instance->subdevice_lock,
2180 cpu_flags);
2181
2182 //Fast copy
2183 copied_values =
2184 ao_write_data(instance, ME4600_AO_FIFO_COUNT / 2,
2185 0);
2186 if (copied_values > 0) {
2187 instance->circ_buf.tail += copied_values;
2188 instance->circ_buf.tail &=
2189 instance->circ_buf.mask;
2190 continue;
2191 }
2192 // Activate interrupts.
2193 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2194 reg_copy = inl(instance->ctrl_reg);
2195 //reg_copy |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
2196 reg_copy &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
2197 outl(reg_copy, instance->ctrl_reg);
2198 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2199 instance->reg_base,
2200 instance->ctrl_reg - instance->reg_base,
2201 reg_copy);
2202 spin_unlock_irqrestore(&instance->subdevice_lock,
2203 cpu_flags);
2204
2205 if (copied_values == 0) { //This was checked and never should happend!
2206 PERROR_CRITICAL("COPING FINISH WITH 0!\n");
2207 }
2208
2209 if (copied_values < 0) { //This was checked and never should happend!
2210 PERROR_CRITICAL
2211 ("COPING FINISH WITH AN ERROR!\n");
2212 instance->status = ao_status_stream_fifo_error;
2213 err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
2214 break;
2215 }
2216 }
2217
2218 if (!left_to_copy_from_user) { //All datas were copied.
2219 break;
2220 } else { //Not all datas were copied.
2221 if (instance->mode & ME4600_AO_WRAP_MODE) { //Error too much datas! Wraparound is limited in size!
2222 PERROR
2223 ("Too much data for wraparound mode! Exceeded size of %ld.\n",
2224 ME4600_AO_CIRC_BUF_COUNT - 1);
2225 err = ME_ERRNO_RING_BUFFER_OVERFLOW;
2226 break;
2227 }
2228
2229 if (write_mode != ME_WRITE_MODE_BLOCKING) { //Non blocking calls
2230 break;
2231 }
2232
2233 wait_event_interruptible(instance->wait_queue,
2234 me_circ_buf_space(&instance->
2235 circ_buf));
2236
2237 if (signal_pending(current)) {
2238 PERROR("Writing interrupted by signal.\n");
2239 instance->status = ao_status_none;
2240 ao_stop_immediately(instance);
2241 err = ME_ERRNO_SIGNAL;
2242 break;
2243 }
2244
2245 if (instance->status == ao_status_none) { //Reset
2246 PERROR("Writing interrupted by reset.\n");
2247 err = ME_ERRNO_CANCELLED;
2248 break;
2249 }
2250 }
2251 }
2252
2253 if (write_mode == ME_WRITE_MODE_PRELOAD) { //Copy data to FIFO - preload
2254 copied_values =
2255 ao_write_data_pooling(instance, ME4600_AO_FIFO_COUNT,
2256 instance->preloaded_count);
2257 instance->preloaded_count += copied_values;
2258 instance->data_count += copied_values;
2259
2260 if ((instance->mode == ME4600_AO_HW_WRAP_MODE)
2261 && (me_circ_buf_values(&instance->circ_buf) >
2262 ME4600_AO_FIFO_COUNT)) {
2263 PERROR
2264 ("Too much data for hardware wraparound mode! Exceeded size of %d.\n",
2265 ME4600_AO_FIFO_COUNT);
2266 err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
2267 }
2268 }
2269
2270 *count = *count - left_to_copy_from_user;
2271 ME_SUBDEVICE_EXIT;
2272
2273 return err;
2274}
2275static irqreturn_t me4600_ao_isr(int irq, void *dev_id
2276#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2277 , struct pt_regs *regs
2278#endif
2279 )
2280{
2281 me4600_ao_subdevice_t *instance = dev_id;
2282 uint32_t irq_status;
2283 uint32_t ctrl;
2284 uint32_t status;
2285 int count = 0;
2286
2287 PDEBUG("executed. idx=%d\n", instance->ao_idx);
2288
2289 if (irq != instance->irq) {
2290 PERROR("Incorrect interrupt num: %d.\n", irq);
2291 return IRQ_NONE;
2292 }
2293
2294 irq_status = inl(instance->irq_status_reg);
2295 if (!(irq_status & (ME4600_IRQ_STATUS_BIT_AO_HF << instance->ao_idx))) {
2296 PINFO("%ld Shared interrupt. %s(): ID=%d: status_reg=0x%04X\n",
2297 jiffies, __FUNCTION__, instance->ao_idx, irq_status);
2298 return IRQ_NONE;
2299 }
2300
2301 if (!instance->circ_buf.buf) {
2302 instance->status = ao_status_stream_error;
2303 PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n");
2304 //Block interrupts. Stop machine.
2305 ctrl = inl(instance->ctrl_reg);
2306 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
2307 ctrl |=
2308 ME4600_AO_CTRL_BIT_RESET_IRQ |
2309 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP;
2310 outl(ctrl, instance->ctrl_reg);
2311 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2312 instance->reg_base,
2313 instance->ctrl_reg - instance->reg_base, ctrl);
2314
2315 //Inform user
2316 wake_up_interruptible_all(&instance->wait_queue);
2317 return IRQ_HANDLED;
2318 }
2319
2320 status = inl(instance->status_reg);
2321 if (!(status & ME4600_AO_STATUS_BIT_FSM)) { //Too late. Not working! END? BROKEN PIPE?
2322 PDEBUG("Interrupt come but ISM is not working!\n");
2323 //Block interrupts. Stop machine.
2324 ctrl = inl(instance->ctrl_reg);
2325 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
2326 ctrl |=
2327 ME4600_AO_CTRL_BIT_RESET_IRQ | ME4600_AO_CTRL_BIT_STOP |
2328 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
2329 outl(ctrl, instance->ctrl_reg);
2330 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2331 instance->reg_base,
2332 instance->ctrl_reg - instance->reg_base, ctrl);
2333
2334 return IRQ_HANDLED;
2335 }
2336 //General procedure. Process more datas.
2337
2338#ifdef MEDEBUG_DEBUG
2339 if (!me_circ_buf_values(&instance->circ_buf)) { //Buffer is empty!
2340 PDEBUG("Circular buffer empty!\n");
2341 }
2342#endif
2343
2344 //Check FIFO
2345 if (status & ME4600_AO_STATUS_BIT_HF) { //OK less than half
2346
2347 //Block interrupts
2348 ctrl = inl(instance->ctrl_reg);
2349 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
2350 ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
2351 outl(ctrl, instance->ctrl_reg);
2352 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2353 instance->reg_base,
2354 instance->ctrl_reg - instance->reg_base, ctrl);
2355
2356 do {
2357 //Calculate how many should be copied.
2358 count =
2359 (instance->stop_data_count) ? instance->
2360 stop_data_count -
2361 instance->data_count : ME4600_AO_FIFO_COUNT / 2;
2362 if (ME4600_AO_FIFO_COUNT / 2 < count) {
2363 count = ME4600_AO_FIFO_COUNT / 2;
2364 }
2365 //Copy data
2366 if (instance->mode == ME4600_AO_CONTINOUS) { //Continous
2367 count = ao_write_data(instance, count, 0);
2368 if (count > 0) {
2369 instance->circ_buf.tail += count;
2370 instance->circ_buf.tail &=
2371 instance->circ_buf.mask;
2372 instance->data_count += count;
2373
2374 if ((instance->status == ao_status_stream_end_wait) && !me_circ_buf_values(&instance->circ_buf)) { //Stoping. Whole buffer was copied.
2375 break;
2376 }
2377 }
2378 } else if ((instance->mode == ME4600_AO_SW_WRAP_MODE) && ((ctrl & ME4600_AO_CTRL_MODE_MASK) == ME4600_AO_MODE_CONTINUOUS)) { //Wraparound (software)
2379 if (instance->status == ao_status_stream_end_wait) { //We stoping => Copy to the end of the buffer.
2380 count =
2381 ao_write_data(instance, count, 0);
2382 } else { //Copy in wraparound mode.
2383 count =
2384 ao_write_data_wraparound(instance,
2385 count,
2386 instance->
2387 preloaded_count);
2388 }
2389
2390 if (count > 0) {
2391 instance->data_count += count;
2392 instance->preloaded_count += count;
2393 instance->preloaded_count %=
2394 me_circ_buf_values(&instance->
2395 circ_buf);
2396
2397 if ((instance->status == ao_status_stream_end_wait) && !instance->preloaded_count) { //Stoping. Whole buffer was copied.
2398 break;
2399 }
2400 }
2401 }
2402
2403 if ((count <= 0) || (instance->stop_data_count && (instance->stop_data_count <= instance->data_count))) { //End of work.
2404 break;
2405 }
2406 } //Repeat if still is under half fifo
2407 while ((status =
2408 inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_HF);
2409
2410 //Unblock interrupts
2411 ctrl = inl(instance->ctrl_reg);
2412 if (count >= 0) { //Copy was successful.
2413 if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. No more interrupts.
2414 PDEBUG("Finishing work. Interrupt disabled.\n");
2415 instance->status = ao_status_stream_end_wait;
2416 } else if (count > 0) { //Normal work. Enable interrupt.
2417 PDEBUG("Normal work. Enable interrupt.\n");
2418 ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
2419 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
2420 } else { //Normal work but there are no more data in buffer. Interrupt active but blocked. stream_write() will unblock it.
2421 PDEBUG
2422 ("No data in software buffer. Interrupt blocked.\n");
2423 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
2424 }
2425 } else { //Error during copy.
2426 instance->status = ao_status_stream_fifo_error;
2427 }
2428
2429 outl(ctrl, instance->ctrl_reg);
2430 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2431 instance->reg_base,
2432 instance->ctrl_reg - instance->reg_base, ctrl);
2433 } else { //?? more than half
2434 PDEBUG
2435 ("Interrupt come but FIFO more than half full! Reset interrupt.\n");
2436 //Reset pending interrupt
2437 ctrl = inl(instance->ctrl_reg);
2438 ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
2439 outl(ctrl, instance->ctrl_reg);
2440 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2441 instance->reg_base,
2442 instance->ctrl_reg - instance->reg_base, ctrl);
2443 ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
2444 outl(ctrl, instance->ctrl_reg);
2445 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2446 instance->reg_base,
2447 instance->ctrl_reg - instance->reg_base, ctrl);
2448 }
2449
2450 PINFO("ISR: Buffer count: %d.(T:%d H:%d)\n",
2451 me_circ_buf_values(&instance->circ_buf), instance->circ_buf.tail,
2452 instance->circ_buf.head);
2453 PINFO("ISR: Stop count: %d.\n", instance->stop_count);
2454 PINFO("ISR: Stop data count: %d.\n", instance->stop_data_count);
2455 PINFO("ISR: Data count: %d.\n", instance->data_count);
2456
2457 //Inform user
2458 wake_up_interruptible_all(&instance->wait_queue);
2459
2460 return IRQ_HANDLED;
2461}
2462
2463static void me4600_ao_destructor(struct me_subdevice *subdevice)
2464{
2465 me4600_ao_subdevice_t *instance;
2466
2467 instance = (me4600_ao_subdevice_t *) subdevice;
2468
2469 PDEBUG("executed. idx=%d\n", instance->ao_idx);
2470
2471 instance->ao_control_task_flag = 0;
2472
2473 // Reset subdevice to asure clean exit.
2474 me4600_ao_io_reset_subdevice(subdevice, NULL,
2475 ME_IO_RESET_SUBDEVICE_NO_FLAGS);
2476
2477 // Remove any tasks from work queue. This is paranoic because it was done allready in reset().
2478 if (!cancel_delayed_work(&instance->ao_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue.
2479 set_current_state(TASK_INTERRUPTIBLE);
2480 schedule_timeout(2);
2481 }
2482
2483 if (instance->fifo) {
2484 if (instance->irq) {
2485 free_irq(instance->irq, instance);
2486 instance->irq = 0;
2487 }
2488
2489 if (instance->circ_buf.buf) {
2490 free_pages((unsigned long)instance->circ_buf.buf,
2491 ME4600_AO_CIRC_BUF_SIZE_ORDER);
2492 }
2493 instance->circ_buf.buf = NULL;
2494 }
2495
2496 me_subdevice_deinit(&instance->base);
2497 kfree(instance);
2498}
2499
2500me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
2501 spinlock_t * preload_reg_lock,
2502 uint32_t * preload_flags,
2503 int ao_idx,
2504 int fifo,
2505 int irq,
2506 struct workqueue_struct *me4600_wq)
2507{
2508 me4600_ao_subdevice_t *subdevice;
2509 int err;
2510
2511 PDEBUG("executed. idx=%d\n", ao_idx);
2512
2513 // Allocate memory for subdevice instance.
2514 subdevice = kmalloc(sizeof(me4600_ao_subdevice_t), GFP_KERNEL);
2515
2516 if (!subdevice) {
2517 PERROR("Cannot get memory for subdevice instance.\n");
2518 return NULL;
2519 }
2520
2521 memset(subdevice, 0, sizeof(me4600_ao_subdevice_t));
2522
2523 // Initialize subdevice base class.
2524 err = me_subdevice_init(&subdevice->base);
2525
2526 if (err) {
2527 PERROR("Cannot initialize subdevice base class instance.\n");
2528 kfree(subdevice);
2529 return NULL;
2530 }
2531 // Initialize spin locks.
2532 spin_lock_init(&subdevice->subdevice_lock);
2533
2534 subdevice->preload_reg_lock = preload_reg_lock;
2535 subdevice->preload_flags = preload_flags;
2536
2537 // Store analog output index.
2538 subdevice->ao_idx = ao_idx;
2539
2540 // Store if analog output has fifo.
2541 subdevice->fifo = (ao_idx < fifo) ? 1 : 0;
2542
2543 if (subdevice->fifo) { // Allocate and initialize circular buffer.
2544 subdevice->circ_buf.mask = ME4600_AO_CIRC_BUF_COUNT - 1;
2545
2546 subdevice->circ_buf.buf =
2547 (void *)__get_free_pages(GFP_KERNEL,
2548 ME4600_AO_CIRC_BUF_SIZE_ORDER);
2549 PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf,
2550 ME4600_AO_CIRC_BUF_SIZE);
2551
2552 if (!subdevice->circ_buf.buf) {
2553 PERROR
2554 ("Cannot initialize subdevice base class instance.\n");
2555 kfree(subdevice);
2556 return NULL;
2557 }
2558
2559 memset(subdevice->circ_buf.buf, 0, ME4600_AO_CIRC_BUF_SIZE);
2560 } else { // No FIFO.
2561 subdevice->circ_buf.mask = 0;
2562 subdevice->circ_buf.buf = NULL;
2563 }
2564
2565 subdevice->circ_buf.head = 0;
2566 subdevice->circ_buf.tail = 0;
2567
2568 subdevice->status = ao_status_none;
2569 subdevice->ao_control_task_flag = 0;
2570 subdevice->timeout.delay = 0;
2571 subdevice->timeout.start_time = jiffies;
2572
2573 // Initialize wait queue.
2574 init_waitqueue_head(&subdevice->wait_queue);
2575
2576 // Initialize single value to 0V.
2577 subdevice->single_value = 0x8000;
2578 subdevice->single_value_in_fifo = 0x8000;
2579
2580 // Register interrupt service routine.
2581 if (subdevice->fifo) {
2582 subdevice->irq = irq;
2583 if (request_irq(subdevice->irq, me4600_ao_isr,
2584#ifdef IRQF_DISABLED
2585 IRQF_DISABLED | IRQF_SHARED,
2586#else
2587 SA_INTERRUPT | SA_SHIRQ,
2588#endif
2589 ME4600_NAME, subdevice)) {
2590 PERROR("Cannot get interrupt line.\n");
2591 PDEBUG("free circ_buf = %p size=%d",
2592 subdevice->circ_buf.buf,
2593 PAGE_SHIFT << ME4600_AO_CIRC_BUF_SIZE_ORDER);
2594 free_pages((unsigned long)subdevice->circ_buf.buf,
2595 ME4600_AO_CIRC_BUF_SIZE_ORDER);
2596 me_subdevice_deinit((me_subdevice_t *) subdevice);
2597 kfree(subdevice);
2598 return NULL;
2599 }
2600 PINFO("Registered irq=%d.\n", subdevice->irq);
2601 } else {
2602 subdevice->irq = 0;
2603 }
2604
2605 // Initialize registers.
2606 subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
2607 subdevice->preload_reg = reg_base + ME4600_AO_SYNC_REG;
2608 if (ao_idx == 0) {
2609 subdevice->ctrl_reg = reg_base + ME4600_AO_00_CTRL_REG;
2610 subdevice->status_reg = reg_base + ME4600_AO_00_STATUS_REG;
2611 subdevice->fifo_reg = reg_base + ME4600_AO_00_FIFO_REG;
2612 subdevice->single_reg = reg_base + ME4600_AO_00_SINGLE_REG;
2613 subdevice->timer_reg = reg_base + ME4600_AO_00_TIMER_REG;
2614 subdevice->reg_base = reg_base;
2615 subdevice->bitpattern = 0;
2616 } else if (ao_idx == 1) {
2617 subdevice->ctrl_reg = reg_base + ME4600_AO_01_CTRL_REG;
2618 subdevice->status_reg = reg_base + ME4600_AO_01_STATUS_REG;
2619 subdevice->fifo_reg = reg_base + ME4600_AO_01_FIFO_REG;
2620 subdevice->single_reg = reg_base + ME4600_AO_01_SINGLE_REG;
2621 subdevice->timer_reg = reg_base + ME4600_AO_01_TIMER_REG;
2622 subdevice->reg_base = reg_base;
2623 subdevice->bitpattern = 0;
2624 } else if (ao_idx == 2) {
2625 subdevice->ctrl_reg = reg_base + ME4600_AO_02_CTRL_REG;
2626 subdevice->status_reg = reg_base + ME4600_AO_02_STATUS_REG;
2627 subdevice->fifo_reg = reg_base + ME4600_AO_02_FIFO_REG;
2628 subdevice->single_reg = reg_base + ME4600_AO_02_SINGLE_REG;
2629 subdevice->timer_reg = reg_base + ME4600_AO_02_TIMER_REG;
2630 subdevice->reg_base = reg_base;
2631 subdevice->bitpattern = 0;
2632 } else if (ao_idx == 3) {
2633 subdevice->ctrl_reg = reg_base + ME4600_AO_03_CTRL_REG;
2634 subdevice->status_reg = reg_base + ME4600_AO_03_STATUS_REG;
2635 subdevice->fifo_reg = reg_base + ME4600_AO_03_FIFO_REG;
2636 subdevice->single_reg = reg_base + ME4600_AO_03_SINGLE_REG;
2637 subdevice->timer_reg = reg_base + ME4600_AO_03_TIMER_REG;
2638 subdevice->reg_base = reg_base;
2639 subdevice->bitpattern = 1;
2640 } else {
2641 PERROR_CRITICAL("WRONG SUBDEVICE idx=%d!", ao_idx);
2642 me_subdevice_deinit((me_subdevice_t *) subdevice);
2643 if (subdevice->fifo) {
2644 free_pages((unsigned long)subdevice->circ_buf.buf,
2645 ME4600_AO_CIRC_BUF_SIZE_ORDER);
2646 }
2647 subdevice->circ_buf.buf = NULL;
2648 kfree(subdevice);
2649 return NULL;
2650 }
2651
2652 // Override base class methods.
2653 subdevice->base.me_subdevice_destructor = me4600_ao_destructor;
2654 subdevice->base.me_subdevice_io_reset_subdevice =
2655 me4600_ao_io_reset_subdevice;
2656 subdevice->base.me_subdevice_io_single_config =
2657 me4600_ao_io_single_config;
2658 subdevice->base.me_subdevice_io_single_read = me4600_ao_io_single_read;
2659 subdevice->base.me_subdevice_io_single_write =
2660 me4600_ao_io_single_write;
2661 subdevice->base.me_subdevice_io_stream_config =
2662 me4600_ao_io_stream_config;
2663 subdevice->base.me_subdevice_io_stream_new_values =
2664 me4600_ao_io_stream_new_values;
2665 subdevice->base.me_subdevice_io_stream_write =
2666 me4600_ao_io_stream_write;
2667 subdevice->base.me_subdevice_io_stream_start =
2668 me4600_ao_io_stream_start;
2669 subdevice->base.me_subdevice_io_stream_status =
2670 me4600_ao_io_stream_status;
2671 subdevice->base.me_subdevice_io_stream_stop = me4600_ao_io_stream_stop;
2672 subdevice->base.me_subdevice_query_number_channels =
2673 me4600_ao_query_number_channels;
2674 subdevice->base.me_subdevice_query_subdevice_type =
2675 me4600_ao_query_subdevice_type;
2676 subdevice->base.me_subdevice_query_subdevice_caps =
2677 me4600_ao_query_subdevice_caps;
2678 subdevice->base.me_subdevice_query_subdevice_caps_args =
2679 me4600_ao_query_subdevice_caps_args;
2680 subdevice->base.me_subdevice_query_range_by_min_max =
2681 me4600_ao_query_range_by_min_max;
2682 subdevice->base.me_subdevice_query_number_ranges =
2683 me4600_ao_query_number_ranges;
2684 subdevice->base.me_subdevice_query_range_info =
2685 me4600_ao_query_range_info;
2686 subdevice->base.me_subdevice_query_timer = me4600_ao_query_timer;
2687
2688 // Prepare work queue
2689 subdevice->me4600_workqueue = me4600_wq;
2690
2691/* workqueue API changed in kernel 2.6.20 */
2692#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
2693 INIT_WORK(&subdevice->ao_control_task, me4600_ao_work_control_task,
2694 (void *)subdevice);
2695#else
2696 INIT_DELAYED_WORK(&subdevice->ao_control_task,
2697 me4600_ao_work_control_task);
2698#endif
2699
2700 if (subdevice->fifo) { // Set speed for single operations.
2701 outl(ME4600_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
2702 subdevice->hardware_stop_delay = HZ / 10; //100ms
2703 }
2704
2705 return subdevice;
2706}
2707
2708/** @brief Stop presentation. Preserve FIFOs.
2709*
2710* @param instance The subdevice instance (pointer).
2711*/
2712int inline ao_stop_immediately(me4600_ao_subdevice_t * instance)
2713{
2714 unsigned long cpu_flags;
2715 uint32_t ctrl;
2716 int timeout;
2717 int i;
2718
2719 timeout =
2720 (instance->hardware_stop_delay >
2721 (HZ / 10)) ? instance->hardware_stop_delay : HZ / 10;
2722 for (i = 0; i <= timeout; i++) {
2723 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2724 // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
2725 ctrl = inl(instance->ctrl_reg);
2726 ctrl |=
2727 ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
2728 | ME4600_AO_CTRL_BIT_RESET_IRQ;
2729 ctrl &=
2730 ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
2731 ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
2732 outl(ctrl, instance->ctrl_reg);
2733 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2734 instance->reg_base,
2735 instance->ctrl_reg - instance->reg_base, ctrl);
2736 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
2737
2738 if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) { // Exit.
2739 break;
2740 }
2741 //Still working!
2742 set_current_state(TASK_INTERRUPTIBLE);
2743 schedule_timeout(1);
2744 }
2745
2746 if (i > timeout) {
2747 PERROR_CRITICAL("FSM IS BUSY!\n");
2748 return ME_ERRNO_INTERNAL;
2749 }
2750 return ME_ERRNO_SUCCESS;
2751}
2752
2753/** @brief Copy data from circular buffer to fifo (fast) in wraparound.
2754* @note This is time critical function. Checking is done at begining and end only.
2755* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
2756*
2757* @param instance The subdevice instance (pointer).
2758* @param count Maximum number of copied data.
2759* @param start_pos Position of the firs value in buffer.
2760*
2761* @return On success: Number of copied data.
2762* @return On error/success: 0. No datas were copied => no data in buffer.
2763* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
2764*/
2765int inline ao_write_data_wraparound(me4600_ao_subdevice_t * instance, int count,
2766 int start_pos)
2767{ /// @note This is time critical function!
2768 uint32_t status;
2769 uint32_t value;
2770 int pos =
2771 (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
2772 int local_count = count;
2773 int i = 1;
2774
2775 if (count <= 0) { //Wrong count!
2776 return 0;
2777 }
2778
2779 while (i < local_count) {
2780 //Get value from buffer
2781 value = *(instance->circ_buf.buf + pos);
2782 //Prepare it
2783 if (instance->ao_idx & 0x1) {
2784 value <<= 16;
2785 }
2786 //Put value to FIFO
2787 outl(value, instance->fifo_reg);
2788 //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
2789
2790 pos++;
2791 pos &= instance->circ_buf.mask;
2792 if (pos == instance->circ_buf.head) {
2793 pos = instance->circ_buf.tail;
2794 }
2795 i++;
2796 }
2797
2798 status = inl(instance->status_reg);
2799 if (!(status & ME4600_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied!
2800 PERROR("FIFO was full before all datas were copied! idx=%d\n",
2801 instance->ao_idx);
2802 return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
2803 } else { //Add last value
2804 value = *(instance->circ_buf.buf + pos);
2805 if (instance->ao_idx & 0x1) {
2806 value <<= 16;
2807 }
2808 //Put value to FIFO
2809 outl(value, instance->fifo_reg);
2810 //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
2811 }
2812
2813 PINFO("WRAPAROUND LOADED %d values. idx=%d\n", local_count,
2814 instance->ao_idx);
2815 return local_count;
2816}
2817
2818/** @brief Copy data from software buffer to fifo (fast).
2819* @note This is time critical function. Checking is done at begining and end only.
2820* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
2821*
2822* @param instance The subdevice instance (pointer).
2823* @param count Maximum number of copied data.
2824* @param start_pos Position of the firs value in buffer.
2825*
2826* @return On success: Number of copied data.
2827* @return On error/success: 0. No datas were copied => no data in buffer.
2828* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
2829*/
2830int inline ao_write_data(me4600_ao_subdevice_t * instance, int count,
2831 int start_pos)
2832{ /// @note This is time critical function!
2833 uint32_t status;
2834 uint32_t value;
2835 int pos =
2836 (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
2837 int local_count = count;
2838 int max_count;
2839 int i = 1;
2840
2841 if (count <= 0) { //Wrong count!
2842 return 0;
2843 }
2844
2845 max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
2846 if (max_count <= 0) { //No data to copy!
2847 return 0;
2848 }
2849
2850 if (max_count < count) {
2851 local_count = max_count;
2852 }
2853
2854 while (i < local_count) {
2855 //Get value from buffer
2856 value = *(instance->circ_buf.buf + pos);
2857 //Prepare it
2858 if (instance->ao_idx & 0x1) {
2859 value <<= 16;
2860 }
2861 //Put value to FIFO
2862 outl(value, instance->fifo_reg);
2863 //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
2864
2865 pos++;
2866 pos &= instance->circ_buf.mask;
2867 i++;
2868 }
2869
2870 status = inl(instance->status_reg);
2871 if (!(status & ME4600_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied!
2872 PERROR("FIFO was full before all datas were copied! idx=%d\n",
2873 instance->ao_idx);
2874 return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
2875 } else { //Add last value
2876 value = *(instance->circ_buf.buf + pos);
2877 if (instance->ao_idx & 0x1) {
2878 value <<= 16;
2879 }
2880 //Put value to FIFO
2881 outl(value, instance->fifo_reg);
2882 //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
2883 }
2884
2885 PINFO("FAST LOADED %d values. idx=%d\n", local_count, instance->ao_idx);
2886 return local_count;
2887}
2888
2889/** @brief Copy data from software buffer to fifo (slow).
2890* @note This is slow function that copy all data from buffer to FIFO with full control.
2891*
2892* @param instance The subdevice instance (pointer).
2893* @param count Maximum number of copied data.
2894* @param start_pos Position of the firs value in buffer.
2895*
2896* @return On success: Number of copied values.
2897* @return On error/success: 0. FIFO was full at begining.
2898* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
2899*/
2900int inline ao_write_data_pooling(me4600_ao_subdevice_t * instance, int count,
2901 int start_pos)
2902{ /// @note This is slow function!
2903 uint32_t status;
2904 uint32_t value;
2905 int pos =
2906 (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
2907 int local_count = count;
2908 int i;
2909 int max_count;
2910
2911 if (count <= 0) { //Wrong count!
2912 PERROR("SLOW LOADED: Wrong count! idx=%d\n", instance->ao_idx);
2913 return 0;
2914 }
2915
2916 max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
2917 if (max_count <= 0) { //No data to copy!
2918 PERROR("SLOW LOADED: No data to copy! idx=%d\n",
2919 instance->ao_idx);
2920 return 0;
2921 }
2922
2923 if (max_count < count) {
2924 local_count = max_count;
2925 }
2926
2927 for (i = 0; i < local_count; i++) {
2928 status = inl(instance->status_reg);
2929 if (!(status & ME4600_AO_STATUS_BIT_FF)) { //FIFO is full!
2930 return i;
2931 }
2932 //Get value from buffer
2933 value = *(instance->circ_buf.buf + pos);
2934 //Prepare it
2935 if (instance->ao_idx & 0x1) {
2936 value <<= 16;
2937 }
2938 //Put value to FIFO
2939 outl(value, instance->fifo_reg);
2940 //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
2941
2942 pos++;
2943 pos &= instance->circ_buf.mask;
2944 }
2945
2946 PINFO("SLOW LOADED %d values. idx=%d\n", local_count, instance->ao_idx);
2947 return local_count;
2948}
2949
2950/** @brief Copy data from user space to circular buffer.
2951* @param instance The subdevice instance (pointer).
2952* @param count Number of datas in user space.
2953* @param user_values Buffer's pointer.
2954*
2955* @return On success: Number of copied values.
2956* @return On error: -ME_ERRNO_INTERNAL.
2957*/
2958int inline ao_get_data_from_user(me4600_ao_subdevice_t * instance, int count,
2959 int *user_values)
2960{
2961 int i, err;
2962 int empty_space;
2963 int copied;
2964 int value;
2965
2966 empty_space = me_circ_buf_space(&instance->circ_buf);
2967 //We have only this space free.
2968 copied = (count < empty_space) ? count : empty_space;
2969 for (i = 0; i < copied; i++) { //Copy from user to buffer
2970 if ((err = get_user(value, (int *)(user_values + i)))) {
2971 PERROR
2972 ("BUFFER LOADED: get_user(0x%p) return an error: %d. idx=%d\n",
2973 user_values + i, err, instance->ao_idx);
2974 return -ME_ERRNO_INTERNAL;
2975 }
2976 /// @note The analog output in me4600 series has size of 16 bits.
2977 *(instance->circ_buf.buf + instance->circ_buf.head) =
2978 (uint16_t) value;
2979 instance->circ_buf.head++;
2980 instance->circ_buf.head &= instance->circ_buf.mask;
2981 }
2982
2983 PINFO("BUFFER LOADED %d values. idx=%d\n", copied, instance->ao_idx);
2984 return copied;
2985}
2986
2987/** @brief Checking actual hardware and logical state.
2988* @param instance The subdevice instance (pointer).
2989*/
2990static void me4600_ao_work_control_task(
2991#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
2992 void *subdevice
2993#else
2994 struct work_struct *work
2995#endif
2996 )
2997{
2998 me4600_ao_subdevice_t *instance;
2999 unsigned long cpu_flags = 0;
3000 uint32_t status;
3001 uint32_t ctrl;
3002 uint32_t synch;
3003 int reschedule = 0;
3004 int signaling = 0;
3005
3006#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
3007 instance = (me4600_ao_subdevice_t *) subdevice;
3008#else
3009 instance =
3010 container_of((void *)work, me4600_ao_subdevice_t, ao_control_task);
3011#endif
3012 PINFO("<%s: %ld> executed. idx=%d\n", __FUNCTION__, jiffies,
3013 instance->ao_idx);
3014
3015 status = inl(instance->status_reg);
3016 PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
3017 instance->status_reg - instance->reg_base, status);
3018
3019 switch (instance->status) { // Checking actual mode.
3020
3021 // Not configured for work.
3022 case ao_status_none:
3023 break;
3024
3025 //This are stable modes. No need to do anything. (?)
3026 case ao_status_single_configured:
3027 case ao_status_stream_configured:
3028 case ao_status_stream_fifo_error:
3029 case ao_status_stream_buffer_error:
3030 case ao_status_stream_error:
3031 PERROR("Shouldn't be running!.\n");
3032 break;
3033
3034 case ao_status_stream_end:
3035 if (!instance->fifo) {
3036 PERROR_CRITICAL
3037 ("Streaming on single device! This feature is not implemented in this version!\n");
3038 instance->status = ao_status_stream_error;
3039 // Signal the end.
3040 signaling = 1;
3041 break;
3042 }
3043 case ao_status_single_end:
3044 if (status & ME4600_AO_STATUS_BIT_FSM) { // State machine is working but the status is set to end. Force stop.
3045
3046 // Wait for stop.
3047 reschedule = 1;
3048 }
3049
3050 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
3051 // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
3052 ctrl = inl(instance->ctrl_reg);
3053 ctrl |=
3054 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP
3055 | ME4600_AO_CTRL_BIT_RESET_IRQ;
3056 ctrl &=
3057 ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
3058 ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
3059 ctrl &=
3060 ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
3061 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
3062 outl(ctrl, instance->ctrl_reg);
3063 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3064 instance->reg_base,
3065 instance->ctrl_reg - instance->reg_base, ctrl);
3066 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
3067 break;
3068
3069 // Single modes
3070 case ao_status_single_run_wait:
3071 case ao_status_single_run:
3072 case ao_status_single_end_wait:
3073
3074 if (!(status & ME4600_AO_STATUS_BIT_FSM)) { // State machine is not working.
3075 if (((instance->fifo)
3076 && (!(status & ME4600_AO_STATUS_BIT_EF)))
3077 || (!(instance->fifo))) { // Single is in end state.
3078 PDEBUG("Single call has been complited.\n");
3079
3080 // Set correct value for single_read();
3081 instance->single_value =
3082 instance->single_value_in_fifo;
3083
3084 // Set status as 'ao_status_single_end'
3085 instance->status = ao_status_single_end;
3086
3087 // Signal the end.
3088 signaling = 1;
3089 // Wait for stop ISM.
3090 reschedule = 1;
3091
3092 break;
3093 }
3094 }
3095 // Check timeout.
3096 if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
3097 PDEBUG("Timeout reached.\n");
3098 // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
3099 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
3100 ctrl = inl(instance->ctrl_reg);
3101 ctrl |=
3102 ME4600_AO_CTRL_BIT_STOP |
3103 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
3104 ME4600_AO_CTRL_BIT_RESET_IRQ;
3105 ctrl &=
3106 ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
3107 ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
3108 /// Fix for timeout error.
3109 ctrl &=
3110 ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
3111 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
3112 if (instance->fifo) { //Disabling FIFO
3113 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO;
3114 }
3115 outl(ctrl, instance->ctrl_reg);
3116 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3117 instance->reg_base,
3118 instance->ctrl_reg - instance->reg_base,
3119 ctrl);
3120 spin_unlock_irqrestore(&instance->subdevice_lock,
3121 cpu_flags);
3122
3123 spin_lock(instance->preload_reg_lock);
3124 //Remove from synchronous start. Block triggering from this output.
3125 synch = inl(instance->preload_reg);
3126 synch &=
3127 ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) <<
3128 instance->ao_idx);
3129 if (!(instance->fifo)) { // No FIFO - set to single safe mode
3130 synch |=
3131 ME4600_AO_SYNC_HOLD << instance->ao_idx;
3132 }
3133 outl(synch, instance->preload_reg);
3134 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
3135 instance->reg_base,
3136 instance->preload_reg - instance->reg_base,
3137 synch);
3138 spin_unlock(instance->preload_reg_lock);
3139
3140 if (!(instance->fifo)) { // No FIFO
3141 // Restore old settings.
3142 PDEBUG("Write old value back to register.\n");
3143 outl(instance->single_value,
3144 instance->single_reg);
3145 PDEBUG_REG
3146 ("single_reg outl(0x%lX+0x%lX)=0x%x\n",
3147 instance->reg_base,
3148 instance->single_reg - instance->reg_base,
3149 instance->single_value);
3150 }
3151 // Set correct value for single_read();
3152 instance->single_value_in_fifo = instance->single_value;
3153
3154 instance->status = ao_status_single_end;
3155
3156 // Signal the end.
3157 signaling = 1;
3158 }
3159 // Wait for stop.
3160 reschedule = 1;
3161 break;
3162
3163 // Stream modes
3164 case ao_status_stream_run_wait:
3165 if (!instance->fifo) {
3166 PERROR_CRITICAL
3167 ("Streaming on single device! This feature is not implemented in this version!\n");
3168 instance->status = ao_status_stream_error;
3169 // Signal the end.
3170 signaling = 1;
3171 break;
3172 }
3173
3174 if (status & ME4600_AO_STATUS_BIT_FSM) { // State machine is working. Waiting for start finish.
3175 instance->status = ao_status_stream_run;
3176
3177 // Signal end of this step
3178 signaling = 1;
3179 } else { // State machine is not working.
3180 if (!(status & ME4600_AO_STATUS_BIT_EF)) { // FIFO is empty. Procedure has started and finish already!
3181 instance->status = ao_status_stream_end;
3182
3183 // Signal the end.
3184 signaling = 1;
3185 // Wait for stop.
3186 reschedule = 1;
3187 break;
3188 }
3189 }
3190
3191 // Check timeout.
3192 if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
3193 PDEBUG("Timeout reached.\n");
3194 // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
3195 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
3196 ctrl = inl(instance->ctrl_reg);
3197 ctrl |=
3198 ME4600_AO_CTRL_BIT_STOP |
3199 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
3200 ME4600_AO_CTRL_BIT_RESET_IRQ;
3201 ctrl &=
3202 ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
3203 ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
3204 outl(ctrl, instance->ctrl_reg);
3205 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3206 instance->reg_base,
3207 instance->ctrl_reg - instance->reg_base,
3208 ctrl);
3209 spin_unlock_irqrestore(&instance->subdevice_lock,
3210 cpu_flags);
3211 spin_lock(instance->preload_reg_lock);
3212 //Remove from synchronous start. Block triggering from this output.
3213 synch = inl(instance->preload_reg);
3214 synch &=
3215 ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) <<
3216 instance->ao_idx);
3217 outl(synch, instance->preload_reg);
3218 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
3219 instance->reg_base,
3220 instance->preload_reg - instance->reg_base,
3221 synch);
3222 spin_unlock(instance->preload_reg_lock);
3223
3224 instance->status = ao_status_stream_end;
3225
3226 // Signal the end.
3227 signaling = 1;
3228 }
3229 // Wait for stop.
3230 reschedule = 1;
3231 break;
3232
3233 case ao_status_stream_run:
3234 if (!instance->fifo) {
3235 PERROR_CRITICAL
3236 ("Streaming on single device! This feature is not implemented in this version!\n");
3237 instance->status = ao_status_stream_error;
3238 // Signal the end.
3239 signaling = 1;
3240 break;
3241 }
3242
3243 if (!(status & ME4600_AO_STATUS_BIT_FSM)) { // State machine is not working. This is an error.
3244 // BROKEN PIPE!
3245 if (!(status & ME4600_AO_STATUS_BIT_EF)) { // FIFO is empty.
3246 if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty.
3247 if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. Requed data shown.
3248 PDEBUG
3249 ("ISM stoped. No data in FIFO. Buffer is not empty.\n");
3250 instance->status =
3251 ao_status_stream_end;
3252 } else {
3253 PERROR
3254 ("Output stream has been broken. ISM stoped. No data in FIFO. Buffer is not empty.\n");
3255 instance->status =
3256 ao_status_stream_buffer_error;
3257 }
3258 } else { // Software buffer is empty.
3259 PDEBUG
3260 ("ISM stoped. No data in FIFO. Buffer is empty.\n");
3261 instance->status = ao_status_stream_end;
3262 }
3263 } else { // There are still datas in FIFO.
3264 if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty.
3265 PERROR
3266 ("Output stream has been broken. ISM stoped but some data in FIFO and buffer.\n");
3267 } else { // Software buffer is empty.
3268 PERROR
3269 ("Output stream has been broken. ISM stoped but some data in FIFO. Buffer is empty.\n");
3270 }
3271 instance->status = ao_status_stream_fifo_error;
3272
3273 }
3274
3275 // Signal the failure.
3276 signaling = 1;
3277 break;
3278 }
3279 // Wait for stop.
3280 reschedule = 1;
3281 break;
3282
3283 case ao_status_stream_end_wait:
3284 if (!instance->fifo) {
3285 PERROR_CRITICAL
3286 ("Streaming on single device! This feature is not implemented in this version!\n");
3287 instance->status = ao_status_stream_error;
3288 // Signal the end.
3289 signaling = 1;
3290 break;
3291 }
3292
3293 if (!(status & ME4600_AO_STATUS_BIT_FSM)) { // State machine is not working. Waiting for stop finish.
3294 instance->status = ao_status_stream_end;
3295 signaling = 1;
3296 }
3297 // State machine is working.
3298 reschedule = 1;
3299 break;
3300
3301 default:
3302 PERROR_CRITICAL("Status is in wrong state (%d)!\n",
3303 instance->status);
3304 instance->status = ao_status_stream_error;
3305 // Signal the end.
3306 signaling = 1;
3307 break;
3308
3309 }
3310
3311 if (signaling) { //Signal it.
3312 wake_up_interruptible_all(&instance->wait_queue);
3313 }
3314
3315 if (instance->ao_control_task_flag && reschedule) { // Reschedule task
3316 queue_delayed_work(instance->me4600_workqueue,
3317 &instance->ao_control_task, 1);
3318 } else {
3319 PINFO("<%s> Ending control task.\n", __FUNCTION__);
3320 }
3321
3322}
3323#else
3324/// @note SPECIAL BUILD FOR BOSCH
3325/// @author Guenter Gebhardt
3326static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
3327 struct file *filep, int flags)
3328{
3329 me4600_ao_subdevice_t *instance;
3330 int err = ME_ERRNO_SUCCESS;
3331 uint32_t tmp;
3332 unsigned long status;
3333
3334 PDEBUG("executed.\n");
3335
3336 instance = (me4600_ao_subdevice_t *) subdevice;
3337
3338 ME_SUBDEVICE_ENTER spin_lock_irqsave(&instance->subdevice_lock, status);
3339 spin_lock(instance->preload_reg_lock);
3340 tmp = inl(instance->preload_reg);
3341 tmp &= ~(0x10001 << instance->ao_idx);
3342 outl(tmp, instance->preload_reg);
3343 *instance->preload_flags &= ~(0x1 << instance->ao_idx);
3344 spin_unlock(instance->preload_reg_lock);
3345
3346 tmp = inl(instance->ctrl_reg);
3347 tmp |= ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3348 outl(tmp, instance->ctrl_reg);
3349
3350 while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ;
3351
3352 outl(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP,
3353 instance->ctrl_reg);
3354
3355 outl(0x8000, instance->single_reg);
3356
3357 instance->single_value = 0x8000;
3358 instance->circ_buf.head = 0;
3359 instance->circ_buf.tail = 0;
3360
3361 spin_unlock_irqrestore(&instance->subdevice_lock, status);
3362
3363 ME_SUBDEVICE_EXIT;
3364
3365 return err;
3366}
3367
3368static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
3369 struct file *filep,
3370 int channel,
3371 int single_config,
3372 int ref,
3373 int trig_chan,
3374 int trig_type, int trig_edge, int flags)
3375{
3376 me4600_ao_subdevice_t *instance;
3377 int err = ME_ERRNO_SUCCESS;
3378 uint32_t tmp;
3379 unsigned long cpu_flags;
3380
3381 PDEBUG("executed.\n");
3382
3383 instance = (me4600_ao_subdevice_t *) subdevice;
3384
3385 ME_SUBDEVICE_ENTER
3386 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
3387
3388 if (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) {
3389 PERROR("Subdevice is busy.\n");
3390 err = ME_ERRNO_SUBDEVICE_BUSY;
3391 goto ERROR;
3392 }
3393
3394 if (channel == 0) {
3395 if (single_config == 0) {
3396 if (ref == ME_REF_AO_GROUND) {
3397 if (trig_chan == ME_TRIG_CHAN_DEFAULT) {
3398 if (trig_type == ME_TRIG_TYPE_SW) {
3399 tmp = inl(instance->ctrl_reg);
3400 tmp |=
3401 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3402 outl(tmp, instance->ctrl_reg);
3403 tmp =
3404 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3405 outl(tmp, instance->ctrl_reg);
3406
3407 spin_lock(instance->
3408 preload_reg_lock);
3409 tmp =
3410 inl(instance->preload_reg);
3411 tmp &=
3412 ~(0x10001 << instance->
3413 ao_idx);
3414 outl(tmp,
3415 instance->preload_reg);
3416 *instance->preload_flags &=
3417 ~(0x1 << instance->ao_idx);
3418 spin_unlock(instance->
3419 preload_reg_lock);
3420 } else if (trig_type ==
3421 ME_TRIG_TYPE_EXT_DIGITAL) {
3422 if (trig_edge ==
3423 ME_TRIG_EDGE_RISING) {
3424 tmp =
3425 inl(instance->
3426 ctrl_reg);
3427 tmp |=
3428 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3429 outl(tmp,
3430 instance->
3431 ctrl_reg);
3432 tmp =
3433 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
3434 |
3435 ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
3436 outl(tmp,
3437 instance->
3438 ctrl_reg);
3439 } else if (trig_edge ==
3440 ME_TRIG_EDGE_FALLING)
3441 {
3442 tmp =
3443 inl(instance->
3444 ctrl_reg);
3445 tmp |=
3446 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3447 outl(tmp,
3448 instance->
3449 ctrl_reg);
3450 tmp =
3451 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
3452 |
3453 ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG
3454 |
3455 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
3456 outl(tmp,
3457 instance->
3458 ctrl_reg);
3459 } else if (trig_edge ==
3460 ME_TRIG_EDGE_ANY) {
3461 tmp =
3462 inl(instance->
3463 ctrl_reg);
3464 tmp |=
3465 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3466 outl(tmp,
3467 instance->
3468 ctrl_reg);
3469 tmp =
3470 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
3471 |
3472 ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG
3473 |
3474 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE
3475 |
3476 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
3477 outl(tmp,
3478 instance->
3479 ctrl_reg);
3480 } else {
3481 PERROR
3482 ("Invalid trigger edge.\n");
3483 err =
3484 ME_ERRNO_INVALID_TRIG_EDGE;
3485 goto ERROR;
3486 }
3487
3488 spin_lock(instance->
3489 preload_reg_lock);
3490
3491 tmp =
3492 inl(instance->preload_reg);
3493 tmp &=
3494 ~(0x10001 << instance->
3495 ao_idx);
3496 tmp |= 0x1 << instance->ao_idx;
3497 outl(tmp,
3498 instance->preload_reg);
3499 *instance->preload_flags &=
3500 ~(0x1 << instance->ao_idx);
3501 spin_unlock(instance->
3502 preload_reg_lock);
3503 } else {
3504 PERROR
3505 ("Invalid trigger type.\n");
3506 err =
3507 ME_ERRNO_INVALID_TRIG_TYPE;
3508 goto ERROR;
3509 }
3510 } else if (trig_chan ==
3511 ME_TRIG_CHAN_SYNCHRONOUS) {
3512 if (trig_type == ME_TRIG_TYPE_SW) {
3513 tmp = inl(instance->ctrl_reg);
3514 tmp |=
3515 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3516 outl(tmp, instance->ctrl_reg);
3517 tmp =
3518 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3519 outl(tmp, instance->ctrl_reg);
3520
3521 spin_lock(instance->
3522 preload_reg_lock);
3523 tmp =
3524 inl(instance->preload_reg);
3525 tmp &=
3526 ~(0x10001 << instance->
3527 ao_idx);
3528 tmp |= 0x1 << instance->ao_idx;
3529 outl(tmp,
3530 instance->preload_reg);
3531 *instance->preload_flags |=
3532 0x1 << instance->ao_idx;
3533 spin_unlock(instance->
3534 preload_reg_lock);
3535 } else if (trig_type ==
3536 ME_TRIG_TYPE_EXT_DIGITAL) {
3537 if (trig_edge ==
3538 ME_TRIG_EDGE_RISING) {
3539 tmp =
3540 inl(instance->
3541 ctrl_reg);
3542 tmp |=
3543 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3544 outl(tmp,
3545 instance->
3546 ctrl_reg);
3547 tmp =
3548 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3549 outl(tmp,
3550 instance->
3551 ctrl_reg);
3552 } else if (trig_edge ==
3553 ME_TRIG_EDGE_FALLING)
3554 {
3555 tmp =
3556 inl(instance->
3557 ctrl_reg);
3558 tmp |=
3559 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3560 outl(tmp,
3561 instance->
3562 ctrl_reg);
3563 tmp =
3564 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
3565 |
3566 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
3567 outl(tmp,
3568 instance->
3569 ctrl_reg);
3570 } else if (trig_edge ==
3571 ME_TRIG_EDGE_ANY) {
3572 tmp =
3573 inl(instance->
3574 ctrl_reg);
3575 tmp |=
3576 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3577 outl(tmp,
3578 instance->
3579 ctrl_reg);
3580 tmp =
3581 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
3582 |
3583 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE
3584 |
3585 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
3586 outl(tmp,
3587 instance->
3588 ctrl_reg);
3589 } else {
3590 PERROR
3591 ("Invalid trigger edge.\n");
3592 err =
3593 ME_ERRNO_INVALID_TRIG_EDGE;
3594 goto ERROR;
3595 }
3596
3597 spin_lock(instance->
3598 preload_reg_lock);
3599
3600 tmp =
3601 inl(instance->preload_reg);
3602 tmp |=
3603 0x10001 << instance->ao_idx;
3604 outl(tmp,
3605 instance->preload_reg);
3606 *instance->preload_flags &=
3607 ~(0x1 << instance->ao_idx);
3608 spin_unlock(instance->
3609 preload_reg_lock);
3610 } else {
3611 PERROR
3612 ("Invalid trigger type.\n");
3613 err =
3614 ME_ERRNO_INVALID_TRIG_TYPE;
3615 goto ERROR;
3616 }
3617 } else {
3618 PERROR
3619 ("Invalid trigger channel specified.\n");
3620 err = ME_ERRNO_INVALID_REF;
3621 goto ERROR;
3622 }
3623 } else {
3624 PERROR("Invalid analog reference specified.\n");
3625 err = ME_ERRNO_INVALID_REF;
3626 goto ERROR;
3627 }
3628 } else {
3629 PERROR("Invalid single config specified.\n");
3630 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
3631 goto ERROR;
3632 }
3633 } else {
3634 PERROR("Invalid channel number specified.\n");
3635 err = ME_ERRNO_INVALID_CHANNEL;
3636 goto ERROR;
3637 }
3638
3639 ERROR:
3640
3641 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
3642
3643 ME_SUBDEVICE_EXIT;
3644
3645 return err;
3646}
3647
3648static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
3649 struct file *filep,
3650 int channel,
3651 int *value, int time_out, int flags)
3652{
3653 me4600_ao_subdevice_t *instance;
3654 int err = ME_ERRNO_SUCCESS;
3655 unsigned long tmp;
3656 unsigned long cpu_flags;
3657
3658 PDEBUG("executed.\n");
3659
3660 instance = (me4600_ao_subdevice_t *) subdevice;
3661
3662 if (channel != 0) {
3663 PERROR("Invalid channel number specified.\n");
3664 return ME_ERRNO_INVALID_CHANNEL;
3665 }
3666
3667 ME_SUBDEVICE_ENTER
3668 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
3669 tmp = inl(instance->ctrl_reg);
3670
3671 if (tmp & 0x3) {
3672 PERROR("Not in single mode.\n");
3673 err = ME_ERRNO_PREVIOUS_CONFIG;
3674 } else {
3675 *value = instance->single_value;
3676 }
3677
3678 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
3679
3680 ME_SUBDEVICE_EXIT;
3681
3682 return err;
3683}
3684
3685static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
3686 struct file *filep,
3687 int channel,
3688 int value, int time_out, int flags)
3689{
3690 me4600_ao_subdevice_t *instance;
3691 int err = ME_ERRNO_SUCCESS;
3692 unsigned long mask = 0;
3693 unsigned long tmp;
3694 unsigned long cpu_flags;
3695 int i;
3696 wait_queue_head_t queue;
3697 unsigned long j;
3698 unsigned long delay = 0;
3699
3700 PDEBUG("executed.\n");
3701
3702 init_waitqueue_head(&queue);
3703
3704 instance = (me4600_ao_subdevice_t *) subdevice;
3705
3706 if (channel != 0) {
3707 PERROR("Invalid channel number specified.\n");
3708 return ME_ERRNO_INVALID_CHANNEL;
3709 }
3710
3711 if (time_out < 0) {
3712 PERROR("Invalid timeout specified.\n");
3713 return ME_ERRNO_INVALID_TIMEOUT;
3714 }
3715
3716 if (time_out) {
3717 delay = (time_out * HZ) / 1000;
3718
3719 if (delay == 0)
3720 delay = 1;
3721 }
3722
3723 ME_SUBDEVICE_ENTER
3724 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
3725
3726 tmp = inl(instance->ctrl_reg);
3727
3728 if (tmp & 0x3) {
3729 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
3730 PERROR("Not in single mode.\n");
3731 err = ME_ERRNO_PREVIOUS_CONFIG;
3732 goto ERROR;
3733 }
3734
3735 if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) {
3736 outl(value, instance->single_reg);
3737 instance->single_value = value;
3738 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
3739
3740 if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
3741 j = jiffies;
3742
3743 while (inl(instance->status_reg) &
3744 ME4600_AO_STATUS_BIT_FSM) {
3745 interruptible_sleep_on_timeout(&queue, 1);
3746
3747 if (signal_pending(current)) {
3748 PERROR
3749 ("Wait on external trigger interrupted by signal.\n");
3750 err = ME_ERRNO_SIGNAL;
3751 goto ERROR;
3752 }
3753
3754 if (delay && ((jiffies - j) > delay)) {
3755 PERROR("Timeout reached.\n");
3756 err = ME_ERRNO_TIMEOUT;
3757 goto ERROR;
3758 }
3759 }
3760 }
3761 } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx))
3762 == (0x10001 << instance->ao_idx)) {
3763 if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {
3764 tmp |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
3765 outl(tmp, instance->ctrl_reg);
3766 outl(value, instance->single_reg);
3767 instance->single_value = value;
3768 spin_unlock_irqrestore(&instance->subdevice_lock,
3769 cpu_flags);
3770
3771 if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
3772 j = jiffies;
3773
3774 while (inl(instance->status_reg) &
3775 ME4600_AO_STATUS_BIT_FSM) {
3776 interruptible_sleep_on_timeout(&queue,
3777 1);
3778
3779 if (signal_pending(current)) {
3780 PERROR
3781 ("Wait on external trigger interrupted by signal.\n");
3782 err = ME_ERRNO_SIGNAL;
3783 goto ERROR;
3784 }
3785
3786 if (delay && ((jiffies - j) > delay)) {
3787 PERROR("Timeout reached.\n");
3788 err = ME_ERRNO_TIMEOUT;
3789 goto ERROR;
3790 }
3791 }
3792 }
3793 } else {
3794 outl(value, instance->single_reg);
3795 instance->single_value = value;
3796 spin_unlock_irqrestore(&instance->subdevice_lock,
3797 cpu_flags);
3798 }
3799 } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx))
3800 == (0x1 << instance->ao_idx)) {
3801 outl(value, instance->single_reg);
3802 instance->single_value = value;
3803
3804 PDEBUG("Synchronous SW, flags = 0x%X.\n", flags);
3805
3806 if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {
3807 PDEBUG("Trigger synchronous SW.\n");
3808 spin_lock(instance->preload_reg_lock);
3809 tmp = inl(instance->preload_reg);
3810
3811 for (i = 0; i < ME4600_AO_MAX_SUBDEVICES; i++) {
3812 if ((*instance->preload_flags & (0x1 << i))) {
3813 if ((tmp & (0x10001 << i)) ==
3814 (0x1 << i)) {
3815 mask |= 0x1 << i;
3816 }
3817 }
3818 }
3819
3820 tmp &= ~(mask);
3821
3822 outl(tmp, instance->preload_reg);
3823 spin_unlock(instance->preload_reg_lock);
3824 }
3825
3826 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
3827 } else {
3828 outl(value, instance->single_reg);
3829 instance->single_value = value;
3830 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
3831 }
3832
3833 ERROR:
3834
3835 ME_SUBDEVICE_EXIT;
3836
3837 return err;
3838}
3839
3840static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
3841 struct file *filep,
3842 meIOStreamConfig_t * config_list,
3843 int count,
3844 meIOStreamTrigger_t * trigger,
3845 int fifo_irq_threshold, int flags)
3846{
3847 me4600_ao_subdevice_t *instance;
3848 int err = ME_ERRNO_SUCCESS;
3849 unsigned long ctrl;
3850 unsigned long tmp;
3851 unsigned long cpu_flags;
3852 uint64_t conv_ticks;
3853 unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
3854 unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
3855
3856 PDEBUG("executed.\n");
3857
3858 instance = (me4600_ao_subdevice_t *) subdevice;
3859
3860 conv_ticks =
3861 (uint64_t) conv_start_ticks_low +
3862 ((uint64_t) conv_start_ticks_high << 32);
3863
3864 if (!instance->fifo) {
3865 PERROR("Not a streaming ao.\n");
3866 return ME_ERRNO_NOT_SUPPORTED;
3867 }
3868
3869 ME_SUBDEVICE_ENTER
3870 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
3871
3872 if ((inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_FSM) {
3873 PERROR("Subdevice is busy.\n");
3874 err = ME_ERRNO_SUBDEVICE_BUSY;
3875 goto ERROR;
3876 }
3877
3878 ctrl = inl(instance->ctrl_reg);
3879 ctrl |= ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3880 outl(ctrl, instance->ctrl_reg);
3881 ctrl = ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
3882 outl(ctrl, instance->ctrl_reg);
3883
3884 if (count != 1) {
3885 PERROR("Invalid stream configuration list count specified.\n");
3886 err = ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
3887 goto ERROR;
3888 }
3889
3890 if (config_list[0].iChannel != 0) {
3891 PERROR("Invalid channel number specified.\n");
3892 err = ME_ERRNO_INVALID_CHANNEL;
3893 goto ERROR;
3894 }
3895
3896 if (config_list[0].iStreamConfig != 0) {
3897 PERROR("Invalid stream config specified.\n");
3898 err = ME_ERRNO_INVALID_STREAM_CONFIG;
3899 goto ERROR;
3900 }
3901
3902 if (config_list[0].iRef != ME_REF_AO_GROUND) {
3903 PERROR("Invalid analog reference.\n");
3904 err = ME_ERRNO_INVALID_REF;
3905 goto ERROR;
3906 }
3907
3908 if ((trigger->iAcqStartTicksLow != 0)
3909 || (trigger->iAcqStartTicksHigh != 0)) {
3910 PERROR
3911 ("Invalid acquisition start trigger argument specified.\n");
3912 err = ME_ERRNO_INVALID_ACQ_START_ARG;
3913 goto ERROR;
3914 }
3915
3916 switch (trigger->iAcqStartTrigType) {
3917
3918 case ME_TRIG_TYPE_SW:
3919 break;
3920
3921 case ME_TRIG_TYPE_EXT_DIGITAL:
3922 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
3923
3924 switch (trigger->iAcqStartTrigEdge) {
3925
3926 case ME_TRIG_EDGE_RISING:
3927 break;
3928
3929 case ME_TRIG_EDGE_FALLING:
3930 ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
3931
3932 break;
3933
3934 case ME_TRIG_EDGE_ANY:
3935 ctrl |=
3936 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
3937 ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
3938
3939 break;
3940
3941 default:
3942 PERROR
3943 ("Invalid acquisition start trigger edge specified.\n");
3944
3945 err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
3946
3947 goto ERROR;
3948
3949 break;
3950 }
3951
3952 break;
3953
3954 default:
3955 PERROR("Invalid acquisition start trigger type specified.\n");
3956
3957 err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
3958
3959 goto ERROR;
3960
3961 break;
3962 }
3963
3964 switch (trigger->iScanStartTrigType) {
3965
3966 case ME_TRIG_TYPE_FOLLOW:
3967 break;
3968
3969 default:
3970 PERROR("Invalid scan start trigger type specified.\n");
3971
3972 err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
3973
3974 goto ERROR;
3975
3976 break;
3977 }
3978
3979 switch (trigger->iConvStartTrigType) {
3980
3981 case ME_TRIG_TYPE_TIMER:
3982 if ((conv_ticks < ME4600_AO_MIN_CHAN_TICKS)
3983 || (conv_ticks > ME4600_AO_MAX_CHAN_TICKS)) {
3984 PERROR
3985 ("Invalid conv start trigger argument specified.\n");
3986 err = ME_ERRNO_INVALID_CONV_START_ARG;
3987 goto ERROR;
3988 }
3989
3990 break;
3991
3992 default:
3993 PERROR("Invalid conv start trigger type specified.\n");
3994
3995 err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
3996
3997 goto ERROR;
3998
3999 break;
4000 }
4001
4002 /* Preset to hardware wraparound mode */
4003 instance->flags &= ~(ME4600_AO_FLAGS_SW_WRAP_MODE_MASK);
4004
4005 switch (trigger->iScanStopTrigType) {
4006
4007 case ME_TRIG_TYPE_NONE:
4008 if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
4009 /* Set flags to indicate usage of software mode. */
4010 instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_INF;
4011 instance->wrap_count = 0;
4012 instance->wrap_remaining = 0;
4013 }
4014
4015 break;
4016
4017 case ME_TRIG_TYPE_COUNT:
4018 if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
4019 if (trigger->iScanStopCount <= 0) {
4020 PERROR("Invalid scan stop count specified.\n");
4021 err = ME_ERRNO_INVALID_SCAN_STOP_ARG;
4022 goto ERROR;
4023 }
4024
4025 /* Set flags to indicate usage of software mode. */
4026 instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_FIN;
4027 instance->wrap_count = trigger->iScanStopCount;
4028 instance->wrap_remaining = trigger->iScanStopCount;
4029 } else {
4030 PERROR("Invalid scan stop trigger type specified.\n");
4031 err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
4032 goto ERROR;
4033 }
4034
4035 break;
4036
4037 default:
4038 PERROR("Invalid scan stop trigger type specified.\n");
4039
4040 err = ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
4041
4042 goto ERROR;
4043
4044 break;
4045 }
4046
4047 switch (trigger->iAcqStopTrigType) {
4048
4049 case ME_TRIG_TYPE_NONE:
4050 break;
4051
4052 case ME_TRIG_TYPE_COUNT:
4053 if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
4054 PERROR("Invalid acq stop trigger type specified.\n");
4055 err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
4056 goto ERROR;
4057 }
4058
4059 if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
4060 if (trigger->iAcqStopCount <= 0) {
4061 PERROR("Invalid acq stop count specified.\n");
4062 err = ME_ERRNO_INVALID_ACQ_STOP_ARG;
4063 goto ERROR;
4064 }
4065
4066 /* Set flags to indicate usage of software mode. */
4067 instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_FIN;
4068 instance->wrap_count = trigger->iAcqStopCount;
4069 instance->wrap_remaining = trigger->iAcqStopCount;
4070 } else {
4071 PERROR("Invalid acp stop trigger type specified.\n");
4072 err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
4073 goto ERROR;
4074 }
4075
4076 break;
4077
4078 default:
4079 PERROR("Invalid acq stop trigger type specified.\n");
4080 err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
4081 goto ERROR;
4082 break;
4083 }
4084
4085 switch (trigger->iAcqStartTrigChan) {
4086
4087 case ME_TRIG_CHAN_DEFAULT:
4088 spin_lock(instance->preload_reg_lock);
4089 tmp = inl(instance->preload_reg);
4090 tmp &= ~(0x10001 << instance->ao_idx);
4091 outl(tmp, instance->preload_reg);
4092 spin_unlock(instance->preload_reg_lock);
4093
4094 break;
4095
4096 case ME_TRIG_CHAN_SYNCHRONOUS:
4097 if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) {
4098 spin_lock(instance->preload_reg_lock);
4099 tmp = inl(instance->preload_reg);
4100 tmp &= ~(0x10001 << instance->ao_idx);
4101 outl(tmp, instance->preload_reg);
4102 tmp |= 0x1 << instance->ao_idx;
4103 outl(tmp, instance->preload_reg);
4104 spin_unlock(instance->preload_reg_lock);
4105 } else {
4106 ctrl &= ~(ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
4107 spin_lock(instance->preload_reg_lock);
4108 tmp = inl(instance->preload_reg);
4109 tmp &= ~(0x10001 << instance->ao_idx);
4110 outl(tmp, instance->preload_reg);
4111 tmp |= 0x10000 << instance->ao_idx;
4112 outl(tmp, instance->preload_reg);
4113 spin_unlock(instance->preload_reg_lock);
4114 }
4115
4116 break;
4117
4118 default:
4119 PERROR("Invalid acq start trigger channel specified.\n");
4120 err = ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
4121 goto ERROR;
4122
4123 break;
4124 }
4125
4126 outl(conv_ticks - 2, instance->timer_reg);
4127
4128 if (flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) {
4129 if (instance->ao_idx == 3) {
4130 ctrl |= ME4600_AO_CTRL_BIT_ENABLE_DO;
4131 } else {
4132 err = ME_ERRNO_INVALID_FLAGS;
4133 goto ERROR;
4134 }
4135 } else {
4136 if (instance->ao_idx == 3) {
4137 ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_DO;
4138 }
4139 }
4140
4141 /* Set hardware mode. */
4142 if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
4143 ctrl |= ME4600_AO_CTRL_BIT_MODE_0;
4144 } else {
4145 ctrl |= ME4600_AO_CTRL_BIT_MODE_1;
4146 }
4147
4148 PDEBUG("Preload word = 0x%X.\n", inl(instance->preload_reg));
4149
4150 PDEBUG("Ctrl word = 0x%lX.\n", ctrl);
4151 outl(ctrl, instance->ctrl_reg); // Write the control word
4152
4153 ERROR:
4154
4155 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
4156
4157 ME_SUBDEVICE_EXIT;
4158
4159 return err;
4160}
4161
4162static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
4163 struct file *filep,
4164 int time_out, int *count, int flags)
4165{
4166 me4600_ao_subdevice_t *instance;
4167 int err = ME_ERRNO_SUCCESS;
4168 long t = 0;
4169 long j;
4170
4171 PDEBUG("executed.\n");
4172
4173 instance = (me4600_ao_subdevice_t *) subdevice;
4174
4175 if (!instance->fifo) {
4176 PERROR("Not a streaming ao.\n");
4177 return ME_ERRNO_NOT_SUPPORTED;
4178 }
4179
4180 if (time_out < 0) {
4181 PERROR("Invalid time_out specified.\n");
4182 return ME_ERRNO_INVALID_TIMEOUT;
4183 }
4184
4185 if (time_out) {
4186 t = (time_out * HZ) / 1000;
4187
4188 if (t == 0)
4189 t = 1;
4190 }
4191
4192 *count = 0;
4193
4194 ME_SUBDEVICE_ENTER;
4195
4196 if (t) {
4197 j = jiffies;
4198 wait_event_interruptible_timeout(instance->wait_queue,
4199 ((me_circ_buf_space
4200 (&instance->circ_buf))
4201 || !(inl(instance->status_reg)
4202 &
4203 ME4600_AO_STATUS_BIT_FSM)),
4204 t);
4205
4206 if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
4207 PERROR("AO subdevice is not running.\n");
4208 err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
4209 } else if (signal_pending(current)) {
4210 PERROR("Wait on values interrupted from signal.\n");
4211 err = ME_ERRNO_SIGNAL;
4212 } else if ((jiffies - j) >= t) {
4213 PERROR("Wait on values timed out.\n");
4214 err = ME_ERRNO_TIMEOUT;
4215 } else {
4216 *count = me_circ_buf_space(&instance->circ_buf);
4217 }
4218 } else {
4219 wait_event_interruptible(instance->wait_queue,
4220 ((me_circ_buf_space
4221 (&instance->circ_buf))
4222 || !(inl(instance->status_reg) &
4223 ME4600_AO_STATUS_BIT_FSM)));
4224
4225 if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
4226 PERROR("AO subdevice is not running.\n");
4227 err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
4228 } else if (signal_pending(current)) {
4229 PERROR("Wait on values interrupted from signal.\n");
4230 err = ME_ERRNO_SIGNAL;
4231 } else {
4232 *count = me_circ_buf_space(&instance->circ_buf);
4233 }
4234 }
4235
4236 ME_SUBDEVICE_EXIT;
4237
4238 return err;
4239}
4240
4241static void stop_immediately(me4600_ao_subdevice_t * instance)
4242{
4243 unsigned long cpu_flags;
4244 uint32_t tmp;
4245
4246 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
4247 tmp = inl(instance->ctrl_reg);
4248 tmp |= ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
4249 outl(tmp, instance->ctrl_reg);
4250
4251 while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ;
4252
4253 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
4254}
4255
4256static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
4257 struct file *filep,
4258 int start_mode, int time_out, int flags)
4259{
4260 me4600_ao_subdevice_t *instance;
4261 int err = ME_ERRNO_SUCCESS;
4262 unsigned long cpu_flags = 0;
4263 unsigned long ref;
4264 unsigned long tmp;
4265 unsigned long delay = 0;
4266 wait_queue_head_t queue;
4267
4268 PDEBUG("executed.\n");
4269
4270 instance = (me4600_ao_subdevice_t *) subdevice;
4271
4272 init_waitqueue_head(&queue);
4273
4274 if (time_out < 0) {
4275 PERROR("Invalid timeout specified.\n");
4276 return ME_ERRNO_INVALID_TIMEOUT;
4277 }
4278
4279 if (time_out) {
4280 delay = (time_out * HZ) / 1000;
4281
4282 if (delay == 0)
4283 delay = 1;
4284 }
4285
4286 if (!instance->fifo) {
4287 PERROR("Not a streaming ao.\n");
4288 return ME_ERRNO_NOT_SUPPORTED;
4289 }
4290
4291 ME_SUBDEVICE_ENTER
4292 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
4293
4294 tmp = inl(instance->ctrl_reg);
4295
4296 switch (tmp & (ME4600_AO_CTRL_MASK_MODE)) {
4297
4298 case 0: // Single mode
4299 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
4300 PERROR("Subdevice is configured in single mode.\n");
4301 err = ME_ERRNO_PREVIOUS_CONFIG;
4302 goto ERROR;
4303
4304 case 1: // Wraparound mode
4305 if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) { // Normal wraparound with external trigger
4306
4307 if ((inl(instance->status_reg) &
4308 ME4600_AO_STATUS_BIT_FSM)) {
4309 spin_unlock_irqrestore(&instance->
4310 subdevice_lock,
4311 cpu_flags);
4312 PERROR("Conversion is already running.\n");
4313 err = ME_ERRNO_SUBDEVICE_BUSY;
4314 goto ERROR;
4315 }
4316
4317 tmp &=
4318 ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
4319 ME4600_AO_CTRL_BIT_STOP |
4320 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
4321
4322 outl(tmp, instance->ctrl_reg);
4323 spin_unlock_irqrestore(&instance->subdevice_lock,
4324 cpu_flags);
4325
4326 if (start_mode == ME_START_MODE_BLOCKING) {
4327 init_waitqueue_head(&queue);
4328
4329 if (delay) {
4330 ref = jiffies;
4331
4332 while (!
4333 (inl(instance->status_reg) &
4334 ME4600_AO_STATUS_BIT_FSM)) {
4335 interruptible_sleep_on_timeout
4336 (&queue, 1);
4337
4338 if (signal_pending(current)) {
4339 PERROR
4340 ("Wait on start of state machine interrupted.\n");
4341 stop_immediately
4342 (instance);
4343 err = ME_ERRNO_SIGNAL;
4344 goto ERROR;
4345 }
4346
4347 if (((jiffies - ref) >= delay)) {
4348 PERROR
4349 ("Timeout reached.\n");
4350 stop_immediately
4351 (instance);
4352 err = ME_ERRNO_TIMEOUT;
4353 goto ERROR;
4354 }
4355 }
4356 } else {
4357 while (!
4358 (inl(instance->status_reg) &
4359 ME4600_AO_STATUS_BIT_FSM)) {
4360 interruptible_sleep_on_timeout
4361 (&queue, 1);
4362
4363 if (signal_pending(current)) {
4364 PERROR
4365 ("Wait on start of state machine interrupted.\n");
4366 stop_immediately
4367 (instance);
4368 err = ME_ERRNO_SIGNAL;
4369 goto ERROR;
4370 }
4371 }
4372 }
4373 } else if (start_mode == ME_START_MODE_NONBLOCKING) {
4374 } else {
4375 PERROR("Invalid start mode specified.\n");
4376 err = ME_ERRNO_INVALID_START_MODE;
4377 goto ERROR;
4378 }
4379 } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x10000 << instance->ao_idx)) { // Synchronous with external trigger
4380
4381 if ((inl(instance->status_reg) &
4382 ME4600_AO_STATUS_BIT_FSM)) {
4383 spin_unlock_irqrestore(&instance->
4384 subdevice_lock,
4385 cpu_flags);
4386 PERROR("Conversion is already running.\n");
4387 err = ME_ERRNO_SUBDEVICE_BUSY;
4388 goto ERROR;
4389 }
4390
4391 if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
4392 tmp |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
4393 tmp &=
4394 ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
4395 ME4600_AO_CTRL_BIT_STOP |
4396 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
4397 outl(tmp, instance->ctrl_reg);
4398 spin_unlock_irqrestore(&instance->
4399 subdevice_lock,
4400 cpu_flags);
4401
4402 if (start_mode == ME_START_MODE_BLOCKING) {
4403 init_waitqueue_head(&queue);
4404
4405 if (delay) {
4406 ref = jiffies;
4407
4408 while (!
4409 (inl
4410 (instance->
4411 status_reg) &
4412 ME4600_AO_STATUS_BIT_FSM))
4413 {
4414 interruptible_sleep_on_timeout
4415 (&queue, 1);
4416
4417 if (signal_pending
4418 (current)) {
4419 PERROR
4420 ("Wait on start of state machine interrupted.\n");
4421 stop_immediately
4422 (instance);
4423 err =
4424 ME_ERRNO_SIGNAL;
4425 goto ERROR;
4426 }
4427
4428 if (((jiffies - ref) >=
4429 delay)) {
4430 PERROR
4431 ("Timeout reached.\n");
4432 stop_immediately
4433 (instance);
4434 err =
4435 ME_ERRNO_TIMEOUT;
4436 goto ERROR;
4437 }
4438 }
4439 } else {
4440 while (!
4441 (inl
4442 (instance->
4443 status_reg) &
4444 ME4600_AO_STATUS_BIT_FSM))
4445 {
4446 interruptible_sleep_on_timeout
4447 (&queue, 1);
4448
4449 if (signal_pending
4450 (current)) {
4451 PERROR
4452 ("Wait on start of state machine interrupted.\n");
4453 stop_immediately
4454 (instance);
4455 err =
4456 ME_ERRNO_SIGNAL;
4457 goto ERROR;
4458 }
4459 }
4460 }
4461 } else if (start_mode ==
4462 ME_START_MODE_NONBLOCKING) {
4463 } else {
4464 PERROR
4465 ("Invalid start mode specified.\n");
4466 err = ME_ERRNO_INVALID_START_MODE;
4467 goto ERROR;
4468 }
4469 } else {
4470 tmp &=
4471 ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
4472 ME4600_AO_CTRL_BIT_STOP |
4473 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
4474 outl(tmp, instance->ctrl_reg);
4475 spin_unlock_irqrestore(&instance->
4476 subdevice_lock,
4477 cpu_flags);
4478 }
4479 } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x1 << instance->ao_idx)) { // Synchronous wraparound with sw trigger
4480
4481 if ((inl(instance->status_reg) &
4482 ME4600_AO_STATUS_BIT_FSM)) {
4483 spin_unlock_irqrestore(&instance->
4484 subdevice_lock,
4485 cpu_flags);
4486 PERROR("Conversion is already running.\n");
4487 err = ME_ERRNO_SUBDEVICE_BUSY;
4488 goto ERROR;
4489 }
4490
4491 tmp &=
4492 ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
4493 ME4600_AO_CTRL_BIT_STOP |
4494 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
4495
4496 outl(tmp, instance->ctrl_reg);
4497
4498 if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
4499 outl(0x8000, instance->single_reg);
4500 instance->single_value = 0x8000;
4501 }
4502
4503 spin_unlock_irqrestore(&instance->subdevice_lock,
4504 cpu_flags);
4505 } else { // Software start
4506
4507 if ((inl(instance->status_reg) &
4508 ME4600_AO_STATUS_BIT_FSM)) {
4509 spin_unlock_irqrestore(&instance->
4510 subdevice_lock,
4511 cpu_flags);
4512 PERROR("Conversion is already running.\n");
4513 err = ME_ERRNO_SUBDEVICE_BUSY;
4514 goto ERROR;
4515 }
4516
4517 tmp &=
4518 ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
4519 ME4600_AO_CTRL_BIT_STOP |
4520 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
4521
4522 outl(tmp, instance->ctrl_reg);
4523
4524 outl(0x8000, instance->single_reg);
4525 instance->single_value = 0x8000;
4526
4527 spin_unlock_irqrestore(&instance->subdevice_lock,
4528 cpu_flags);
4529 }
4530
4531 break;
4532
4533 case 2: // Continuous mode
4534 if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) { // Externally triggered
4535
4536 if ((inl(instance->status_reg) &
4537 ME4600_AO_STATUS_BIT_FSM)) {
4538 spin_unlock_irqrestore(&instance->
4539 subdevice_lock,
4540 cpu_flags);
4541 PERROR("Conversion is already running.\n");
4542 err = ME_ERRNO_SUBDEVICE_BUSY;
4543 goto ERROR;
4544 }
4545
4546 tmp &=
4547 ~(ME4600_AO_CTRL_BIT_STOP |
4548 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
4549 tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
4550 outl(tmp, instance->ctrl_reg);
4551 instance->wrap_remaining = instance->wrap_count;
4552 instance->circ_buf.tail = 0;
4553 spin_unlock_irqrestore(&instance->subdevice_lock,
4554 cpu_flags);
4555
4556 if (start_mode == ME_START_MODE_BLOCKING) {
4557 init_waitqueue_head(&queue);
4558
4559 if (delay) {
4560 ref = jiffies;
4561
4562 while (!
4563 (inl(instance->status_reg) &
4564 ME4600_AO_STATUS_BIT_FSM)) {
4565 interruptible_sleep_on_timeout
4566 (&queue, 1);
4567
4568 if (signal_pending(current)) {
4569 PERROR
4570 ("Wait on start of state machine interrupted.\n");
4571 stop_immediately
4572 (instance);
4573 err = ME_ERRNO_SIGNAL;
4574 goto ERROR;
4575 }
4576
4577 if (((jiffies - ref) >= delay)) {
4578 PERROR
4579 ("Timeout reached.\n");
4580 stop_immediately
4581 (instance);
4582 err = ME_ERRNO_TIMEOUT;
4583 goto ERROR;
4584 }
4585 }
4586 } else {
4587 while (!
4588 (inl(instance->status_reg) &
4589 ME4600_AO_STATUS_BIT_FSM)) {
4590 interruptible_sleep_on_timeout
4591 (&queue, 1);
4592
4593 if (signal_pending(current)) {
4594 PERROR
4595 ("Wait on start of state machine interrupted.\n");
4596 stop_immediately
4597 (instance);
4598 err = ME_ERRNO_SIGNAL;
4599 goto ERROR;
4600 }
4601 }
4602 }
4603 } else if (start_mode == ME_START_MODE_NONBLOCKING) {
4604 /* Do nothing */
4605 } else {
4606 PERROR("Invalid start mode specified.\n");
4607 stop_immediately(instance);
4608 err = ME_ERRNO_INVALID_START_MODE;
4609 goto ERROR;
4610 }
4611 } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x10000 << instance->ao_idx)) { // Synchronous with external trigger
4612
4613 if ((inl(instance->status_reg) &
4614 ME4600_AO_STATUS_BIT_FSM)) {
4615 spin_unlock_irqrestore(&instance->
4616 subdevice_lock,
4617 cpu_flags);
4618 PERROR("Conversion is already running.\n");
4619 err = ME_ERRNO_SUBDEVICE_BUSY;
4620 goto ERROR;
4621 }
4622
4623 if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
4624 tmp |=
4625 ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG |
4626 ME4600_AO_CTRL_BIT_ENABLE_IRQ;
4627 tmp &=
4628 ~(ME4600_AO_CTRL_BIT_STOP |
4629 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
4630 outl(tmp, instance->ctrl_reg);
4631 instance->wrap_remaining = instance->wrap_count;
4632 instance->circ_buf.tail = 0;
4633
4634 spin_unlock_irqrestore(&instance->
4635 subdevice_lock,
4636 cpu_flags);
4637
4638 if (start_mode == ME_START_MODE_BLOCKING) {
4639 init_waitqueue_head(&queue);
4640
4641 if (delay) {
4642 ref = jiffies;
4643
4644 while (!
4645 (inl
4646 (instance->
4647 status_reg) &
4648 ME4600_AO_STATUS_BIT_FSM))
4649 {
4650 interruptible_sleep_on_timeout
4651 (&queue, 1);
4652
4653 if (signal_pending
4654 (current)) {
4655 PERROR
4656 ("Wait on start of state machine interrupted.\n");
4657 stop_immediately
4658 (instance);
4659 err =
4660 ME_ERRNO_SIGNAL;
4661 goto ERROR;
4662 }
4663
4664 if (((jiffies - ref) >=
4665 delay)) {
4666 PERROR
4667 ("Timeout reached.\n");
4668 stop_immediately
4669 (instance);
4670 err =
4671 ME_ERRNO_TIMEOUT;
4672 goto ERROR;
4673 }
4674 }
4675 } else {
4676 while (!
4677 (inl
4678 (instance->
4679 status_reg) &
4680 ME4600_AO_STATUS_BIT_FSM))
4681 {
4682 interruptible_sleep_on_timeout
4683 (&queue, 1);
4684
4685 if (signal_pending
4686 (current)) {
4687 PERROR
4688 ("Wait on start of state machine interrupted.\n");
4689 stop_immediately
4690 (instance);
4691 err =
4692 ME_ERRNO_SIGNAL;
4693 goto ERROR;
4694 }
4695 }
4696 }
4697 } else if (start_mode ==
4698 ME_START_MODE_NONBLOCKING) {
4699 } else {
4700 PERROR
4701 ("Invalid start mode specified.\n");
4702 stop_immediately(instance);
4703 err = ME_ERRNO_INVALID_START_MODE;
4704 goto ERROR;
4705 }
4706 } else {
4707 tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
4708 tmp &=
4709 ~(ME4600_AO_CTRL_BIT_STOP |
4710 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
4711 outl(tmp, instance->ctrl_reg);
4712 instance->wrap_remaining = instance->wrap_count;
4713 instance->circ_buf.tail = 0;
4714 spin_unlock_irqrestore(&instance->
4715 subdevice_lock,
4716 cpu_flags);
4717 }
4718 } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x1 << instance->ao_idx)) { // Synchronous wraparound with sw trigger
4719
4720 if ((inl(instance->status_reg) &
4721 ME4600_AO_STATUS_BIT_FSM)) {
4722 spin_unlock_irqrestore(&instance->
4723 subdevice_lock,
4724 cpu_flags);
4725 PERROR("Conversion is already running.\n");
4726 err = ME_ERRNO_SUBDEVICE_BUSY;
4727 goto ERROR;
4728 }
4729
4730 tmp &=
4731 ~(ME4600_AO_CTRL_BIT_STOP |
4732 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
4733 tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
4734 instance->wrap_remaining = instance->wrap_count;
4735 instance->circ_buf.tail = 0;
4736 PDEBUG("CTRL Reg = 0x%X.\n", inl(instance->ctrl_reg));
4737 outl(tmp, instance->ctrl_reg);
4738
4739 if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
4740 outl(0x8000, instance->single_reg);
4741 instance->single_value = 0x8000;
4742 }
4743
4744 spin_unlock_irqrestore(&instance->subdevice_lock,
4745 cpu_flags);
4746 } else { // Software start
4747
4748 if ((inl(instance->status_reg) &
4749 ME4600_AO_STATUS_BIT_FSM)) {
4750 spin_unlock_irqrestore(&instance->
4751 subdevice_lock,
4752 cpu_flags);
4753 PERROR("Conversion is already running.\n");
4754 err = ME_ERRNO_SUBDEVICE_BUSY;
4755 goto ERROR;
4756 }
4757
4758 tmp &=
4759 ~(ME4600_AO_CTRL_BIT_STOP |
4760 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
4761
4762 tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
4763 outl(tmp, instance->ctrl_reg);
4764 outl(0x8000, instance->single_reg);
4765 instance->single_value = 0x8000;
4766 instance->wrap_remaining = instance->wrap_count;
4767 instance->circ_buf.tail = 0;
4768 spin_unlock_irqrestore(&instance->subdevice_lock,
4769 cpu_flags);
4770 }
4771
4772 break;
4773
4774 default:
4775 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
4776 PERROR("Invalid mode configured.\n");
4777 err = ME_ERRNO_INTERNAL;
4778 goto ERROR;
4779 }
4780
4781 ERROR:
4782
4783 ME_SUBDEVICE_EXIT;
4784
4785 return err;
4786}
4787
4788static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
4789 struct file *filep,
4790 int wait,
4791 int *status, int *values, int flags)
4792{
4793 me4600_ao_subdevice_t *instance;
4794 int err = ME_ERRNO_SUCCESS;
4795 wait_queue_head_t queue;
4796
4797 PDEBUG("executed.\n");
4798
4799 instance = (me4600_ao_subdevice_t *) subdevice;
4800
4801 init_waitqueue_head(&queue);
4802
4803 if (!instance->fifo) {
4804 PERROR("Not a streaming ao.\n");
4805 return ME_ERRNO_NOT_SUPPORTED;
4806 }
4807
4808 ME_SUBDEVICE_ENTER;
4809
4810 if (wait == ME_WAIT_NONE) {
4811 *status =
4812 (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ?
4813 ME_STATUS_BUSY : ME_STATUS_IDLE;
4814 *values = me_circ_buf_space(&instance->circ_buf);
4815 } else if (wait == ME_WAIT_IDLE) {
4816 while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) {
4817 interruptible_sleep_on_timeout(&queue, 1);
4818
4819 if (instance->flags & ME4600_AO_FLAGS_BROKEN_PIPE) {
4820 PERROR("Output stream was interrupted.\n");
4821 *status = ME_STATUS_ERROR;
4822 err = ME_ERRNO_SUCCESS;
4823 goto ERROR;
4824 }
4825
4826 if (signal_pending(current)) {
4827 PERROR
4828 ("Wait on state machine interrupted by signal.\n");
4829 *status = ME_STATUS_INVALID;
4830 err = ME_ERRNO_SIGNAL;
4831 goto ERROR;
4832 }
4833 }
4834
4835 *status = ME_STATUS_IDLE;
4836
4837 *values = me_circ_buf_space(&instance->circ_buf);
4838 } else {
4839 PERROR("Invalid wait argument specified.\n");
4840 *status = ME_STATUS_INVALID;
4841 err = ME_ERRNO_INVALID_WAIT;
4842 goto ERROR;
4843 }
4844
4845 ERROR:
4846
4847 ME_SUBDEVICE_EXIT;
4848
4849 return err;
4850}
4851
4852static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
4853 struct file *filep,
4854 int stop_mode, int flags)
4855{
4856 int err = ME_ERRNO_SUCCESS;
4857 me4600_ao_subdevice_t *instance;
4858 unsigned long cpu_flags;
4859 unsigned long tmp;
4860
4861 PDEBUG("executed.\n");
4862
4863 instance = (me4600_ao_subdevice_t *) subdevice;
4864
4865 if (!instance->fifo) {
4866 PERROR("Not a streaming ao.\n");
4867 return ME_ERRNO_NOT_SUPPORTED;
4868 }
4869
4870 ME_SUBDEVICE_ENTER;
4871
4872 if (stop_mode == ME_STOP_MODE_IMMEDIATE) {
4873 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
4874 tmp = inl(instance->ctrl_reg);
4875 tmp |=
4876 ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
4877 outl(tmp, instance->ctrl_reg);
4878
4879 while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ;
4880
4881 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
4882 } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
4883 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
4884 tmp = inl(instance->ctrl_reg);
4885 tmp |= ME4600_AO_CTRL_BIT_STOP;
4886 outl(tmp, instance->ctrl_reg);
4887 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
4888 } else {
4889 PERROR("Invalid stop mode specified.\n");
4890 err = ME_ERRNO_INVALID_STOP_MODE;
4891 goto ERROR;
4892 }
4893
4894 ERROR:
4895
4896 ME_SUBDEVICE_EXIT;
4897
4898 return err;
4899}
4900
4901static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
4902 struct file *filep,
4903 int write_mode,
4904 int *values, int *count, int flags)
4905{
4906 int err = ME_ERRNO_SUCCESS;
4907 me4600_ao_subdevice_t *instance;
4908 unsigned long tmp;
4909 int i;
4910 int value;
4911 int cnt = *count;
4912 int c;
4913 int k;
4914 int ret = 0;
4915 unsigned long cpu_flags = 0;
4916
4917 PDEBUG("executed.\n");
4918
4919 instance = (me4600_ao_subdevice_t *) subdevice;
4920
4921 if (!instance->fifo) {
4922 PERROR("Not a streaming ao.\n");
4923 return ME_ERRNO_NOT_SUPPORTED;
4924 }
4925
4926 ME_SUBDEVICE_ENTER;
4927
4928 if (*count <= 0) {
4929 PERROR("Invalid count of values specified.\n");
4930 err = ME_ERRNO_INVALID_VALUE_COUNT;
4931 goto ERROR;
4932 }
4933
4934 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
4935
4936 tmp = inl(instance->ctrl_reg);
4937
4938 switch (tmp & 0x3) {
4939
4940 case 1: // Wraparound mode
4941 if (instance->bosch_fw) { // Bosch firmware
4942 spin_unlock_irqrestore(&instance->subdevice_lock,
4943 cpu_flags);
4944
4945 if (cnt != 7) {
4946 PERROR
4947 ("Invalid count of values specified. 7 expected.\n");
4948 err = ME_ERRNO_INVALID_VALUE_COUNT;
4949 goto ERROR;
4950 }
4951
4952 for (i = 0; i < 7; i++) {
4953 if (get_user(value, values)) {
4954 PERROR
4955 ("Can't copy value from user space.\n");
4956 err = ME_ERRNO_INTERNAL;
4957 goto ERROR;
4958 }
4959
4960 if (i == 0) {
4961 /* Maximum voltage */
4962 value <<= 16;
4963 value |=
4964 inl(instance->reg_base +
4965 0xD4) & 0xFFFF;
4966 outl(value, instance->reg_base + 0xD4);
4967 } else if (i == 1) {
4968 /* Minimum voltage */
4969 value &= 0xFFFF;
4970 value |=
4971 inl(instance->reg_base +
4972 0xD4) & 0xFFFF0000;
4973 outl(value, instance->reg_base + 0xD4);
4974 } else if (i == 2) {
4975 /* Delta up */
4976 value <<= 16;
4977 value |=
4978 inl(instance->reg_base +
4979 0xD8) & 0xFFFF;
4980 outl(value, instance->reg_base + 0xD8);
4981 } else if (i == 3) {
4982 /* Delta down */
4983 value &= 0xFFFF;
4984 value |=
4985 inl(instance->reg_base +
4986 0xD8) & 0xFFFF0000;
4987 outl(value, instance->reg_base + 0xD8);
4988 } else if (i == 4) {
4989 /* Start value */
4990 outl(value, instance->reg_base + 0xDC);
4991 } else if (i == 5) {
4992 /* Invert */
4993 if (value) {
4994 value = inl(instance->ctrl_reg);
4995 value |= 0x100;
4996 outl(value, instance->ctrl_reg);
4997 } else {
4998 value = inl(instance->ctrl_reg);
4999 value &= ~0x100;
5000 outl(value, instance->ctrl_reg);
5001 }
5002 } else if (i == 6) {
5003 /* Timer for positive ramp */
5004 outl(value, instance->reg_base + 0xE0);
5005 }
5006
5007 values++;
5008 }
5009 } else { // Normal firmware
5010 PDEBUG("Write for wraparound mode.\n");
5011
5012 if (inl(instance->status_reg) &
5013 ME4600_AO_STATUS_BIT_FSM) {
5014 spin_unlock_irqrestore(&instance->
5015 subdevice_lock,
5016 cpu_flags);
5017 PERROR
5018 ("There is already a conversion running.\n");
5019 err = ME_ERRNO_SUBDEVICE_BUSY;
5020 goto ERROR;
5021 }
5022
5023 tmp |= ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
5024 tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO;
5025 outl(tmp, instance->ctrl_reg);
5026 tmp |= ME4600_AO_CTRL_BIT_ENABLE_FIFO;
5027
5028 if ((*count > ME4600_AO_FIFO_COUNT) ||
5029 ((instance->
5030 flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
5031 ME4600_AO_FLAGS_SW_WRAP_MODE_FIN)) {
5032 tmp &=
5033 ~(ME4600_AO_CTRL_BIT_MODE_0 |
5034 ME4600_AO_CTRL_BIT_MODE_1);
5035 tmp |= ME4600_AO_CTRL_BIT_MODE_1;
5036 }
5037
5038 outl(tmp, instance->ctrl_reg);
5039 spin_unlock_irqrestore(&instance->subdevice_lock,
5040 cpu_flags);
5041
5042 if ((*count <= ME4600_AO_FIFO_COUNT) &&
5043 ((instance->
5044 flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
5045 ME4600_AO_FLAGS_SW_WRAP_MODE_INF)) {
5046 for (i = 0; i < *count; i++) {
5047 if (get_user(value, values + i)) {
5048 PERROR
5049 ("Cannot copy value from user space.\n");
5050 err = ME_ERRNO_INTERNAL;
5051 goto ERROR;
5052 }
5053
5054 if (instance->ao_idx & 0x1)
5055 value <<= 16;
5056
5057 outl(value, instance->fifo_reg);
5058 }
5059 } else if ((*count <= ME4600_AO_CIRC_BUF_COUNT) &&
5060 ((instance->
5061 flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK)
5062 == ME4600_AO_FLAGS_SW_WRAP_MODE_INF)) {
5063 for (i = 0; i < *count; i++) {
5064 if (get_user(value, values + i)) {
5065 PERROR
5066 ("Cannot copy value from user space.\n");
5067 err = ME_ERRNO_INTERNAL;
5068 goto ERROR;
5069 }
5070
5071 instance->circ_buf.buf[i] = value; /* Used to hold the values. */
5072 }
5073
5074 instance->circ_buf.tail = 0; /* Used as the current read position. */
5075 instance->circ_buf.head = *count; /* Used as the buffer size. */
5076
5077 /* Preload the FIFO. */
5078
5079 for (i = 0; i < ME4600_AO_FIFO_COUNT;
5080 i++, instance->circ_buf.tail++) {
5081 if (instance->circ_buf.tail >=
5082 instance->circ_buf.head)
5083 instance->circ_buf.tail = 0;
5084
5085 if (instance->ao_idx & 0x1)
5086 outl(instance->circ_buf.
5087 buf[instance->circ_buf.
5088 tail] << 16,
5089 instance->fifo_reg);
5090 else
5091 outl(instance->circ_buf.
5092 buf[instance->circ_buf.
5093 tail],
5094 instance->fifo_reg);
5095 }
5096 } else if ((*count <= ME4600_AO_CIRC_BUF_COUNT) &&
5097 ((instance->
5098 flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK)
5099 == ME4600_AO_FLAGS_SW_WRAP_MODE_FIN)) {
5100 unsigned int preload_count;
5101
5102 for (i = 0; i < *count; i++) {
5103 if (get_user(value, values + i)) {
5104 PERROR
5105 ("Cannot copy value from user space.\n");
5106 err = ME_ERRNO_INTERNAL;
5107 goto ERROR;
5108 }
5109
5110 instance->circ_buf.buf[i] = value; /* Used to hold the values. */
5111 }
5112
5113 instance->circ_buf.tail = 0; /* Used as the current read position. */
5114 instance->circ_buf.head = *count; /* Used as the buffer size. */
5115
5116 /* Try to preload the whole FIFO. */
5117 preload_count = ME4600_AO_FIFO_COUNT;
5118
5119 if (preload_count > instance->wrap_count)
5120 preload_count = instance->wrap_count;
5121
5122 /* Preload the FIFO. */
5123 for (i = 0; i < preload_count;
5124 i++, instance->circ_buf.tail++) {
5125 if (instance->circ_buf.tail >=
5126 instance->circ_buf.head)
5127 instance->circ_buf.tail = 0;
5128
5129 if (instance->ao_idx & 0x1)
5130 outl(instance->circ_buf.
5131 buf[instance->circ_buf.
5132 tail] << 16,
5133 instance->fifo_reg);
5134 else
5135 outl(instance->circ_buf.
5136 buf[instance->circ_buf.
5137 tail],
5138 instance->fifo_reg);
5139 }
5140
5141 instance->wrap_remaining =
5142 instance->wrap_count - preload_count;
5143 } else {
5144 PERROR("To many values written.\n");
5145 err = ME_ERRNO_INVALID_VALUE_COUNT;
5146 goto ERROR;
5147 }
5148 }
5149
5150 break;
5151
5152 case 2: // Continuous mode
5153 /* Check if in SW wrapround mode */
5154 if (instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) {
5155 spin_unlock_irqrestore(&instance->subdevice_lock,
5156 cpu_flags);
5157 PERROR("Subdevice is configured SW wrapround mode.\n");
5158 err = ME_ERRNO_PREVIOUS_CONFIG;
5159 goto ERROR;
5160 }
5161
5162 switch (write_mode) {
5163
5164 case ME_WRITE_MODE_BLOCKING:
5165 spin_unlock_irqrestore(&instance->subdevice_lock,
5166 cpu_flags);
5167
5168 PDEBUG("Write for blocking continuous mode.\n");
5169
5170 while (cnt > 0) {
5171 wait_event_interruptible(instance->wait_queue,
5172 (c =
5173 me_circ_buf_space_to_end
5174 (&instance->
5175 circ_buf)));
5176
5177 if (instance->
5178 flags & ME4600_AO_FLAGS_BROKEN_PIPE) {
5179 PERROR
5180 ("Broken pipe in blocking write.\n");
5181 err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
5182 goto ERROR;
5183 } else if (signal_pending(current)) {
5184 PERROR
5185 ("Wait for free buffer interrupted from signal.\n");
5186 err = ME_ERRNO_SIGNAL;
5187 goto ERROR;
5188 }
5189
5190 PDEBUG("Space to end = %d.\n", c);
5191
5192 /* Only able to write size of free buffer or size of count */
5193
5194 if (cnt < c)
5195 c = cnt;
5196 k = sizeof(int) * c;
5197 k -= copy_from_user(instance->circ_buf.buf +
5198 instance->circ_buf.head,
5199 values, k);
5200 c = k / sizeof(int);
5201
5202 PDEBUG("Copy %d values from user space.\n", c);
5203
5204 if (!c) {
5205 PERROR
5206 ("Cannot copy values from user space.\n");
5207 err = ME_ERRNO_INTERNAL;
5208 goto ERROR;
5209 }
5210
5211 instance->circ_buf.head =
5212 (instance->circ_buf.head +
5213 c) & (instance->circ_buf.mask);
5214
5215 values += c;
5216 cnt -= c;
5217 ret += c;
5218
5219 /* Values are now available so enable interrupts */
5220 spin_lock_irqsave(&instance->subdevice_lock,
5221 cpu_flags);
5222
5223 if (me_circ_buf_space(&instance->circ_buf)) {
5224 tmp = inl(instance->ctrl_reg);
5225 tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
5226 outl(tmp, instance->ctrl_reg);
5227 }
5228
5229 spin_unlock_irqrestore(&instance->
5230 subdevice_lock,
5231 cpu_flags);
5232 }
5233
5234 *count = ret;
5235
5236 break;
5237
5238 case ME_WRITE_MODE_NONBLOCKING:
5239 spin_unlock_irqrestore(&instance->subdevice_lock,
5240 cpu_flags);
5241
5242 PDEBUG("Write for non blocking continuous mode.\n");
5243
5244 while (cnt > 0) {
5245 if (instance->
5246 flags & ME4600_AO_FLAGS_BROKEN_PIPE) {
5247 PERROR
5248 ("ME4600:Broken pipe in nonblocking write.\n");
5249 err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
5250 goto ERROR;
5251 }
5252
5253 c = me_circ_buf_space_to_end(&instance->
5254 circ_buf);
5255
5256 if (!c) {
5257 PDEBUG
5258 ("Returning from nonblocking write.\n");
5259 break;
5260 }
5261
5262 PDEBUG("Space to end = %d.\n", c);
5263
5264 /* Only able to write size of free buffer or size of count */
5265
5266 if (cnt < c)
5267 c = cnt;
5268 k = sizeof(int) * c;
5269 k -= copy_from_user(instance->circ_buf.buf +
5270 instance->circ_buf.head,
5271 values, k);
5272 c = k / sizeof(int);
5273
5274 PDEBUG("Copy %d values from user space.\n", c);
5275
5276 if (!c) {
5277 PERROR
5278 ("Cannot copy values from user space.\n");
5279 err = ME_ERRNO_INTERNAL;
5280 goto ERROR;
5281 }
5282
5283 instance->circ_buf.head =
5284 (instance->circ_buf.head +
5285 c) & (instance->circ_buf.mask);
5286
5287 values += c;
5288 cnt -= c;
5289 ret += c;
5290
5291 /* Values are now available so enable interrupts */
5292 spin_lock_irqsave(&instance->subdevice_lock,
5293 cpu_flags);
5294
5295 if (me_circ_buf_space(&instance->circ_buf)) {
5296 tmp = inl(instance->ctrl_reg);
5297 tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
5298 outl(tmp, instance->ctrl_reg);
5299 }
5300
5301 spin_unlock_irqrestore(&instance->
5302 subdevice_lock,
5303 cpu_flags);
5304 }
5305
5306 *count = ret;
5307
5308 break;
5309
5310 case ME_WRITE_MODE_PRELOAD:
5311 PDEBUG("Write for preload continuous mode.\n");
5312
5313 if ((inl(instance->status_reg) &
5314 ME4600_AO_STATUS_BIT_FSM)) {
5315 spin_unlock_irqrestore(&instance->
5316 subdevice_lock,
5317 cpu_flags);
5318 PERROR
5319 ("Can't Preload DAC FIFO while conversion is running.\n");
5320 err = ME_ERRNO_SUBDEVICE_BUSY;
5321 goto ERROR;
5322 }
5323
5324 tmp = inl(instance->ctrl_reg);
5325
5326 tmp |=
5327 ME4600_AO_CTRL_BIT_STOP |
5328 ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
5329 outl(tmp, instance->ctrl_reg);
5330 tmp &=
5331 ~(ME4600_AO_CTRL_BIT_ENABLE_FIFO |
5332 ME4600_AO_CTRL_BIT_ENABLE_IRQ);
5333 outl(tmp, instance->ctrl_reg);
5334 tmp |= ME4600_AO_CTRL_BIT_ENABLE_FIFO;
5335 outl(tmp, instance->ctrl_reg);
5336
5337 instance->circ_buf.head = 0;
5338 instance->circ_buf.tail = 0;
5339 instance->flags &= ~ME4600_AO_FLAGS_BROKEN_PIPE;
5340
5341 spin_unlock_irqrestore(&instance->subdevice_lock,
5342 cpu_flags);
5343
5344 c = ME4600_AO_FIFO_COUNT;
5345
5346 if (cnt < c)
5347 c = cnt;
5348
5349 for (i = 0; i < c; i++) {
5350 if (get_user(value, values)) {
5351 PERROR
5352 ("Can't copy value from user space.\n");
5353 err = ME_ERRNO_INTERNAL;
5354 goto ERROR;
5355 }
5356
5357 if (instance->ao_idx & 0x1)
5358 value <<= 16;
5359
5360 outl(value, instance->fifo_reg);
5361
5362 values++;
5363 }
5364
5365 cnt -= c;
5366
5367 ret += c;
5368
5369 PDEBUG("Wrote %d values to fifo.\n", c);
5370
5371 while (1) {
5372 c = me_circ_buf_space_to_end(&instance->
5373 circ_buf);
5374
5375 if (c == 0)
5376 break;
5377
5378 if (cnt < c)
5379 c = cnt;
5380
5381 if (c <= 0)
5382 break;
5383
5384 k = sizeof(int) * c;
5385
5386 k -= copy_from_user(instance->circ_buf.buf +
5387 instance->circ_buf.head,
5388 values, k);
5389
5390 c = k / sizeof(int);
5391
5392 PDEBUG("Wrote %d values to circular buffer.\n",
5393 c);
5394
5395 if (!c) {
5396 PERROR
5397 ("Can't copy values from user space.\n");
5398 err = ME_ERRNO_INTERNAL;
5399 goto ERROR;
5400 }
5401
5402 instance->circ_buf.head =
5403 (instance->circ_buf.head +
5404 c) & (instance->circ_buf.mask);
5405
5406 values += c;
5407 cnt -= c;
5408 ret += c;
5409 }
5410
5411 *count = ret;
5412
5413 break;
5414
5415 default:
5416 spin_unlock_irqrestore(&instance->subdevice_lock,
5417 cpu_flags);
5418
5419 PERROR("Invalid write mode specified.\n");
5420
5421 err = ME_ERRNO_INVALID_WRITE_MODE;
5422
5423 goto ERROR;
5424 }
5425
5426 break;
5427
5428 default: // Single mode of invalid
5429 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
5430 PERROR("Subdevice is configured in single mode.\n");
5431 err = ME_ERRNO_PREVIOUS_CONFIG;
5432 goto ERROR;
5433 }
5434
5435 ERROR:
5436
5437 ME_SUBDEVICE_EXIT;
5438
5439 return err;
5440}
5441
5442#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
5443static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
5444#else
5445static irqreturn_t me4600_ao_isr(int irq, void *dev_id, struct pt_regs *regs)
5446#endif
5447{
5448 unsigned long tmp;
5449 int value;
5450 me4600_ao_subdevice_t *instance = dev_id;
5451 int i;
5452 int c = 0;
5453 int c1 = 0;
5454
5455 if (irq != instance->irq) {
5456 PDEBUG("Incorrect interrupt num: %d.\n", irq);
5457 return IRQ_NONE;
5458 }
5459
5460 if (!((0x1 << (instance->ao_idx + 3)) & inl(instance->irq_status_reg))) {
5461 return IRQ_NONE;
5462 }
5463
5464 PDEBUG("executed.\n");
5465
5466 tmp = inl(instance->status_reg);
5467
5468 if (!(tmp & ME4600_AO_STATUS_BIT_EF) &&
5469 (tmp & ME4600_AO_STATUS_BIT_HF) &&
5470 (tmp & ME4600_AO_STATUS_BIT_HF)) {
5471 c = ME4600_AO_FIFO_COUNT;
5472 PDEBUG("Fifo empty.\n");
5473 } else if ((tmp & ME4600_AO_STATUS_BIT_EF) &&
5474 (tmp & ME4600_AO_STATUS_BIT_HF) &&
5475 (tmp & ME4600_AO_STATUS_BIT_HF)) {
5476 c = ME4600_AO_FIFO_COUNT / 2;
5477 PDEBUG("Fifo under half full.\n");
5478 } else {
5479 c = 0;
5480 PDEBUG("Fifo full.\n");
5481 }
5482
5483 PDEBUG("Try to write 0x%04X values.\n", c);
5484
5485 if ((instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
5486 ME4600_AO_FLAGS_SW_WRAP_MODE_INF) {
5487 while (c) {
5488 c1 = c;
5489
5490 if (c1 > (instance->circ_buf.head - instance->circ_buf.tail)) /* Only up to the end of the buffer */
5491 c1 = (instance->circ_buf.head -
5492 instance->circ_buf.tail);
5493
5494 /* Write the values to the FIFO */
5495 for (i = 0; i < c1; i++, instance->circ_buf.tail++, c--) {
5496 if (instance->ao_idx & 0x1)
5497 outl(instance->circ_buf.
5498 buf[instance->circ_buf.tail] << 16,
5499 instance->fifo_reg);
5500 else
5501 outl(instance->circ_buf.
5502 buf[instance->circ_buf.tail],
5503 instance->fifo_reg);
5504 }
5505
5506 if (instance->circ_buf.tail >= instance->circ_buf.head) /* Start from beginning */
5507 instance->circ_buf.tail = 0;
5508 }
5509
5510 spin_lock(&instance->subdevice_lock);
5511
5512 tmp = inl(instance->ctrl_reg);
5513 tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ;
5514 outl(tmp, instance->ctrl_reg);
5515 tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
5516 outl(tmp, instance->ctrl_reg);
5517
5518 if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
5519 PERROR("Broken pipe.\n");
5520 instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE;
5521 tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
5522 outl(tmp, instance->ctrl_reg);
5523 }
5524
5525 spin_unlock(&instance->subdevice_lock);
5526 } else if ((instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
5527 ME4600_AO_FLAGS_SW_WRAP_MODE_FIN) {
5528 while (c && instance->wrap_remaining) {
5529 c1 = c;
5530
5531 if (c1 > (instance->circ_buf.head - instance->circ_buf.tail)) /* Only up to the end of the buffer */
5532 c1 = (instance->circ_buf.head -
5533 instance->circ_buf.tail);
5534
5535 if (c1 > instance->wrap_remaining) /* Only up to count of user defined number of values */
5536 c1 = instance->wrap_remaining;
5537
5538 /* Write the values to the FIFO */
5539 for (i = 0; i < c1;
5540 i++, instance->circ_buf.tail++, c--,
5541 instance->wrap_remaining--) {
5542 if (instance->ao_idx & 0x1)
5543 outl(instance->circ_buf.
5544 buf[instance->circ_buf.tail] << 16,
5545 instance->fifo_reg);
5546 else
5547 outl(instance->circ_buf.
5548 buf[instance->circ_buf.tail],
5549 instance->fifo_reg);
5550 }
5551
5552 if (instance->circ_buf.tail >= instance->circ_buf.head) /* Start from beginning */
5553 instance->circ_buf.tail = 0;
5554 }
5555
5556 spin_lock(&instance->subdevice_lock);
5557
5558 tmp = inl(instance->ctrl_reg);
5559
5560 if (!instance->wrap_remaining) {
5561 PDEBUG("Finite SW wraparound done.\n");
5562 tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
5563 }
5564
5565 tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ;
5566
5567 outl(tmp, instance->ctrl_reg);
5568 tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
5569 outl(tmp, instance->ctrl_reg);
5570
5571 if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
5572 PERROR("Broken pipe.\n");
5573 instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE;
5574 tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
5575 outl(tmp, instance->ctrl_reg);
5576 }
5577
5578 spin_unlock(&instance->subdevice_lock);
5579
5580 } else { /* Regular continuous mode */
5581
5582 while (1) {
5583 c1 = me_circ_buf_values_to_end(&instance->circ_buf);
5584 PDEBUG("Values to end = %d.\n", c1);
5585
5586 if (c1 > c)
5587 c1 = c;
5588
5589 if (c1 <= 0) {
5590 PDEBUG("Work done or buffer empty.\n");
5591 break;
5592 }
5593
5594 if (instance->ao_idx & 0x1) {
5595 for (i = 0; i < c1; i++) {
5596 value =
5597 *(instance->circ_buf.buf +
5598 instance->circ_buf.tail +
5599 i) << 16;
5600 outl(value, instance->fifo_reg);
5601 }
5602 } else
5603 outsl(instance->fifo_reg,
5604 instance->circ_buf.buf +
5605 instance->circ_buf.tail, c1);
5606
5607 instance->circ_buf.tail =
5608 (instance->circ_buf.tail +
5609 c1) & (instance->circ_buf.mask);
5610
5611 PDEBUG("%d values wrote to port 0x%04X.\n", c1,
5612 instance->fifo_reg);
5613
5614 c -= c1;
5615 }
5616
5617 spin_lock(&instance->subdevice_lock);
5618
5619 tmp = inl(instance->ctrl_reg);
5620
5621 if (!me_circ_buf_values(&instance->circ_buf)) {
5622 PDEBUG
5623 ("Disable Interrupt because no values left in buffer.\n");
5624 tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
5625 }
5626
5627 tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ;
5628
5629 outl(tmp, instance->ctrl_reg);
5630 tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
5631 outl(tmp, instance->ctrl_reg);
5632
5633 if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
5634 PDEBUG("Broken pipe in me4600_ao_isr.\n");
5635 instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE;
5636 tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
5637 outl(tmp, instance->ctrl_reg);
5638 }
5639
5640 spin_unlock(&instance->subdevice_lock);
5641
5642 wake_up_interruptible(&instance->wait_queue);
5643 }
5644
5645 return IRQ_HANDLED;
5646}
5647
5648static void me4600_ao_destructor(struct me_subdevice *subdevice)
5649{
5650 me4600_ao_subdevice_t *instance;
5651
5652 PDEBUG("executed.\n");
5653
5654 instance = (me4600_ao_subdevice_t *) subdevice;
5655
5656 free_irq(instance->irq, instance);
5657 kfree(instance->circ_buf.buf);
5658 me_subdevice_deinit(&instance->base);
5659 kfree(instance);
5660}
5661
5662me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
5663 spinlock_t * preload_reg_lock,
5664 uint32_t * preload_flags,
5665 int ao_idx, int fifo, int irq)
5666{
5667 me4600_ao_subdevice_t *subdevice;
5668 int err;
5669
5670 PDEBUG("executed.\n");
5671
5672 /* Allocate memory for subdevice instance */
5673 subdevice = kmalloc(sizeof(me4600_ao_subdevice_t), GFP_KERNEL);
5674
5675 if (!subdevice) {
5676 PERROR("Cannot get memory for subdevice instance.\n");
5677 return NULL;
5678 }
5679
5680 memset(subdevice, 0, sizeof(me4600_ao_subdevice_t));
5681
5682 /* Initialize subdevice base class */
5683 err = me_subdevice_init(&subdevice->base);
5684
5685 if (err) {
5686 PERROR("Cannot initialize subdevice base class instance.\n");
5687 kfree(subdevice);
5688 return NULL;
5689 }
5690 // Initialize spin locks.
5691 spin_lock_init(&subdevice->subdevice_lock);
5692
5693 subdevice->preload_reg_lock = preload_reg_lock;
5694 subdevice->preload_flags = preload_flags;
5695
5696 /* Allocate and initialize circular buffer */
5697 subdevice->circ_buf.mask = ME4600_AO_CIRC_BUF_COUNT - 1;
5698 subdevice->circ_buf.buf = kmalloc(ME4600_AO_CIRC_BUF_SIZE, GFP_KERNEL);
5699
5700 if (!subdevice->circ_buf.buf) {
5701 PERROR("Cannot initialize subdevice base class instance.\n");
5702 me_subdevice_deinit((me_subdevice_t *) subdevice);
5703 kfree(subdevice);
5704 return NULL;
5705 }
5706
5707 memset(subdevice->circ_buf.buf, 0, ME4600_AO_CIRC_BUF_SIZE);
5708
5709 subdevice->circ_buf.head = 0;
5710 subdevice->circ_buf.tail = 0;
5711
5712 /* Initialize wait queue */
5713 init_waitqueue_head(&subdevice->wait_queue);
5714
5715 /* Initialize single value to 0V */
5716 subdevice->single_value = 0x8000;
5717
5718 /* Store analog output index */
5719 subdevice->ao_idx = ao_idx;
5720
5721 /* Store if analog output has fifo */
5722 subdevice->fifo = fifo;
5723
5724 /* Initialize registers */
5725
5726 if (ao_idx == 0) {
5727 subdevice->ctrl_reg = reg_base + ME4600_AO_00_CTRL_REG;
5728 subdevice->status_reg = reg_base + ME4600_AO_00_STATUS_REG;
5729 subdevice->fifo_reg = reg_base + ME4600_AO_00_FIFO_REG;
5730 subdevice->single_reg = reg_base + ME4600_AO_00_SINGLE_REG;
5731 subdevice->timer_reg = reg_base + ME4600_AO_00_TIMER_REG;
5732 subdevice->reg_base = reg_base;
5733
5734 if (inl(subdevice->reg_base + ME4600_AO_BOSCH_REG) == 0x20000) {
5735 PINFO("Bosch firmware in use for channel 0.\n");
5736 subdevice->bosch_fw = 1;
5737 } else {
5738 subdevice->bosch_fw = 0;
5739 }
5740 } else if (ao_idx == 1) {
5741 subdevice->ctrl_reg = reg_base + ME4600_AO_01_CTRL_REG;
5742 subdevice->status_reg = reg_base + ME4600_AO_01_STATUS_REG;
5743 subdevice->fifo_reg = reg_base + ME4600_AO_01_FIFO_REG;
5744 subdevice->single_reg = reg_base + ME4600_AO_01_SINGLE_REG;
5745 subdevice->timer_reg = reg_base + ME4600_AO_01_TIMER_REG;
5746 subdevice->reg_base = reg_base;
5747 subdevice->bosch_fw = 0;
5748 } else if (ao_idx == 2) {
5749 subdevice->ctrl_reg = reg_base + ME4600_AO_02_CTRL_REG;
5750 subdevice->status_reg = reg_base + ME4600_AO_02_STATUS_REG;
5751 subdevice->fifo_reg = reg_base + ME4600_AO_02_FIFO_REG;
5752 subdevice->single_reg = reg_base + ME4600_AO_02_SINGLE_REG;
5753 subdevice->timer_reg = reg_base + ME4600_AO_02_TIMER_REG;
5754 subdevice->reg_base = reg_base;
5755 subdevice->bosch_fw = 0;
5756 } else {
5757 subdevice->ctrl_reg = reg_base + ME4600_AO_03_CTRL_REG;
5758 subdevice->status_reg = reg_base + ME4600_AO_03_STATUS_REG;
5759 subdevice->fifo_reg = reg_base + ME4600_AO_03_FIFO_REG;
5760 subdevice->single_reg = reg_base + ME4600_AO_03_SINGLE_REG;
5761 subdevice->timer_reg = reg_base + ME4600_AO_03_TIMER_REG;
5762 subdevice->reg_base = reg_base;
5763 subdevice->bosch_fw = 0;
5764 }
5765
5766 subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
5767 subdevice->preload_reg = reg_base + ME4600_AO_LOADSETREG_XX;
5768
5769 /* Register interrupt service routine */
5770 subdevice->irq = irq;
5771
5772 if (request_irq
5773 (subdevice->irq, me4600_ao_isr, SA_INTERRUPT | SA_SHIRQ,
5774 ME4600_NAME, subdevice)) {
5775 PERROR("Cannot get interrupt line.\n");
5776 me_subdevice_deinit((me_subdevice_t *) subdevice);
5777 kfree(subdevice->circ_buf.buf);
5778 kfree(subdevice);
5779 return NULL;
5780 }
5781
5782 /* Override base class methods. */
5783 subdevice->base.me_subdevice_destructor = me4600_ao_destructor;
5784 subdevice->base.me_subdevice_io_reset_subdevice =
5785 me4600_ao_io_reset_subdevice;
5786 subdevice->base.me_subdevice_io_single_config =
5787 me4600_ao_io_single_config;
5788 subdevice->base.me_subdevice_io_single_read = me4600_ao_io_single_read;
5789 subdevice->base.me_subdevice_io_single_write =
5790 me4600_ao_io_single_write;
5791 subdevice->base.me_subdevice_io_stream_config =
5792 me4600_ao_io_stream_config;
5793 subdevice->base.me_subdevice_io_stream_new_values =
5794 me4600_ao_io_stream_new_values;
5795 subdevice->base.me_subdevice_io_stream_write =
5796 me4600_ao_io_stream_write;
5797 subdevice->base.me_subdevice_io_stream_start =
5798 me4600_ao_io_stream_start;
5799 subdevice->base.me_subdevice_io_stream_status =
5800 me4600_ao_io_stream_status;
5801 subdevice->base.me_subdevice_io_stream_stop = me4600_ao_io_stream_stop;
5802 subdevice->base.me_subdevice_query_number_channels =
5803 me4600_ao_query_number_channels;
5804 subdevice->base.me_subdevice_query_subdevice_type =
5805 me4600_ao_query_subdevice_type;
5806 subdevice->base.me_subdevice_query_subdevice_caps =
5807 me4600_ao_query_subdevice_caps;
5808 subdevice->base.me_subdevice_query_subdevice_caps_args =
5809 me4600_ao_query_subdevice_caps_args;
5810 subdevice->base.me_subdevice_query_range_by_min_max =
5811 me4600_ao_query_range_by_min_max;
5812 subdevice->base.me_subdevice_query_number_ranges =
5813 me4600_ao_query_number_ranges;
5814 subdevice->base.me_subdevice_query_range_info =
5815 me4600_ao_query_range_info;
5816 subdevice->base.me_subdevice_query_timer = me4600_ao_query_timer;
5817
5818 return subdevice;
5819}
5820
5821#endif // BOSCH
5822
5823/* Common functions
5824*/
5825
5826static int me4600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
5827 int unit,
5828 int *min,
5829 int *max, int *maxdata, int *range)
5830{
5831 me4600_ao_subdevice_t *instance;
5832
5833 instance = (me4600_ao_subdevice_t *) subdevice;
5834
5835 PDEBUG("executed. idx=%d\n", instance->ao_idx);
5836
5837 if ((*max - *min) < 0) {
5838 PERROR("Invalid minimum and maximum values specified.\n");
5839 return ME_ERRNO_INVALID_MIN_MAX;
5840 }
5841
5842 if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
5843 if ((*max <= (ME4600_AO_MAX_RANGE + 1000))
5844 && (*min >= ME4600_AO_MIN_RANGE)) {
5845 *min = ME4600_AO_MIN_RANGE;
5846 *max = ME4600_AO_MAX_RANGE;
5847 *maxdata = ME4600_AO_MAX_DATA;
5848 *range = 0;
5849 } else {
5850 PERROR("No matching range available.\n");
5851 return ME_ERRNO_NO_RANGE;
5852 }
5853 } else {
5854 PERROR("Invalid physical unit specified.\n");
5855 return ME_ERRNO_INVALID_UNIT;
5856 }
5857
5858 return ME_ERRNO_SUCCESS;
5859}
5860
5861static int me4600_ao_query_number_ranges(me_subdevice_t * subdevice,
5862 int unit, int *count)
5863{
5864 me4600_ao_subdevice_t *instance;
5865
5866 instance = (me4600_ao_subdevice_t *) subdevice;
5867
5868 PDEBUG("executed. idx=%d\n", instance->ao_idx);
5869
5870 if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
5871 *count = 1;
5872 } else {
5873 *count = 0;
5874 }
5875
5876 return ME_ERRNO_SUCCESS;
5877}
5878
5879static int me4600_ao_query_range_info(me_subdevice_t * subdevice,
5880 int range,
5881 int *unit,
5882 int *min, int *max, int *maxdata)
5883{
5884 me4600_ao_subdevice_t *instance;
5885
5886 instance = (me4600_ao_subdevice_t *) subdevice;
5887
5888 PDEBUG("executed. idx=%d\n", instance->ao_idx);
5889
5890 if (range == 0) {
5891 *unit = ME_UNIT_VOLT;
5892 *min = ME4600_AO_MIN_RANGE;
5893 *max = ME4600_AO_MAX_RANGE;
5894 *maxdata = ME4600_AO_MAX_DATA;
5895 } else {
5896 PERROR("Invalid range number specified.\n");
5897 return ME_ERRNO_INVALID_RANGE;
5898 }
5899
5900 return ME_ERRNO_SUCCESS;
5901}
5902
5903static int me4600_ao_query_timer(me_subdevice_t * subdevice,
5904 int timer,
5905 int *base_frequency,
5906 long long *min_ticks, long long *max_ticks)
5907{
5908 me4600_ao_subdevice_t *instance;
5909
5910 instance = (me4600_ao_subdevice_t *) subdevice;
5911
5912 PDEBUG("executed. idx=%d\n", instance->ao_idx);
5913
5914 if ((timer != ME_TIMER_ACQ_START) && (timer != ME_TIMER_CONV_START)) {
5915 PERROR("Invalid timer specified.\n");
5916 return ME_ERRNO_INVALID_TIMER;
5917 }
5918
5919 if (instance->fifo) { //Streaming device.
5920 *base_frequency = ME4600_AO_BASE_FREQUENCY;
5921 if (timer == ME_TIMER_ACQ_START) {
5922 *min_ticks = ME4600_AO_MIN_ACQ_TICKS;
5923 *max_ticks = ME4600_AO_MAX_ACQ_TICKS;
5924 } else if (timer == ME_TIMER_CONV_START) {
5925 *min_ticks = ME4600_AO_MIN_CHAN_TICKS;
5926 *max_ticks = ME4600_AO_MAX_CHAN_TICKS;
5927 }
5928 } else { //Not streaming device!
5929 *base_frequency = 0;
5930 *min_ticks = 0;
5931 *max_ticks = 0;
5932 }
5933
5934 return ME_ERRNO_SUCCESS;
5935}
5936
5937static int me4600_ao_query_number_channels(me_subdevice_t * subdevice,
5938 int *number)
5939{
5940 me4600_ao_subdevice_t *instance;
5941 instance = (me4600_ao_subdevice_t *) subdevice;
5942
5943 PDEBUG("executed. idx=%d\n", instance->ao_idx);
5944
5945 *number = 1;
5946
5947 return ME_ERRNO_SUCCESS;
5948}
5949
5950static int me4600_ao_query_subdevice_type(me_subdevice_t * subdevice,
5951 int *type, int *subtype)
5952{
5953 me4600_ao_subdevice_t *instance;
5954
5955 instance = (me4600_ao_subdevice_t *) subdevice;
5956
5957 PDEBUG("executed. idx=%d\n", instance->ao_idx);
5958
5959 *type = ME_TYPE_AO;
5960 *subtype = (instance->fifo) ? ME_SUBTYPE_STREAMING : ME_SUBTYPE_SINGLE;
5961
5962 return ME_ERRNO_SUCCESS;
5963}
5964
5965static int me4600_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
5966{
5967 me4600_ao_subdevice_t *instance;
5968 instance = (me4600_ao_subdevice_t *) subdevice;
5969
5970 PDEBUG("executed. idx=%d\n", instance->ao_idx);
5971
5972 *caps =
5973 ME_CAPS_AO_TRIG_SYNCHRONOUS | ((instance->fifo) ? ME_CAPS_AO_FIFO :
5974 ME_CAPS_NONE);
5975
5976 return ME_ERRNO_SUCCESS;
5977}
5978
5979static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
5980 int cap, int *args, int count)
5981{
5982 me4600_ao_subdevice_t *instance;
5983 int err = ME_ERRNO_SUCCESS;
5984
5985 instance = (me4600_ao_subdevice_t *) subdevice;
5986
5987 PDEBUG("executed. idx=%d\n", instance->ao_idx);
5988
5989 if (count != 1) {
5990 PERROR("Invalid capability argument count.\n");
5991 return ME_ERRNO_INVALID_CAP_ARG_COUNT;
5992 }
5993
5994 switch (cap) {
5995 case ME_CAP_AI_FIFO_SIZE:
5996 args[0] = (instance->fifo) ? ME4600_AO_FIFO_COUNT : 0;
5997 break;
5998
5999 case ME_CAP_AI_BUFFER_SIZE:
6000 args[0] =
6001 (instance->circ_buf.buf) ? ME4600_AO_CIRC_BUF_COUNT : 0;
6002 break;
6003
6004 default:
6005 PERROR("Invalid capability.\n");
6006 err = ME_ERRNO_INVALID_CAP;
6007 args[0] = 0;
6008 }
6009
6010 return err;
6011}
diff --git a/drivers/staging/meilhaus/me4600_ao.h b/drivers/staging/meilhaus/me4600_ao.h
new file mode 100644
index 000000000000..6fbc4a2dd9dd
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_ao.h
@@ -0,0 +1,263 @@
1/**
2 * @file me4600_ao.h
3 *
4 * @brief Meilhaus ME-4000 analog output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME4600_AO_H_
28# define _ME4600_AO_H_
29
30# include <linux/version.h>
31# include "mesubdevice.h"
32# include "mecirc_buf.h"
33# include "meioctl.h"
34
35# ifdef __KERNEL__
36
37# ifdef BOSCH
38# undef ME_SYNAPSE
39# ifndef _CBUFF_32b_t
40# define _CBUFF_32b_t
41# endif //_CBUFF_32b_t
42# endif //BOSCH
43
44# define ME4600_AO_MAX_SUBDEVICES 4
45# define ME4600_AO_FIFO_COUNT 4096
46
47# define ME4600_AO_BASE_FREQUENCY 33000000LL
48
49# define ME4600_AO_MIN_ACQ_TICKS 0LL
50# define ME4600_AO_MAX_ACQ_TICKS 0LL
51
52# define ME4600_AO_MIN_CHAN_TICKS 66LL
53# define ME4600_AO_MAX_CHAN_TICKS 0xFFFFFFFFLL
54
55# define ME4600_AO_MIN_RANGE -10000000
56# define ME4600_AO_MAX_RANGE 9999694
57
58# define ME4600_AO_MAX_DATA 0xFFFF
59
60# ifdef ME_SYNAPSE
61# define ME4600_AO_CIRC_BUF_SIZE_ORDER 8 // 2^n PAGES =>> Maximum value of 1MB for Synapse
62# else
63# define ME4600_AO_CIRC_BUF_SIZE_ORDER 5 // 2^n PAGES =>> 128KB
64# endif
65# define ME4600_AO_CIRC_BUF_SIZE PAGE_SIZE<<ME4600_AO_CIRC_BUF_SIZE_ORDER // Buffer size in bytes.
66
67# ifdef _CBUFF_32b_t
68# define ME4600_AO_CIRC_BUF_COUNT ((ME4600_AO_CIRC_BUF_SIZE) / sizeof(uint32_t)) // Size in values
69# else
70# define ME4600_AO_CIRC_BUF_COUNT ((ME4600_AO_CIRC_BUF_SIZE) / sizeof(uint16_t)) // Size in values
71# endif
72
73# define ME4600_AO_CONTINOUS 0x0
74# define ME4600_AO_WRAP_MODE 0x1
75# define ME4600_AO_HW_MODE 0x2
76
77# define ME4600_AO_HW_WRAP_MODE (ME4600_AO_WRAP_MODE | ME4600_AO_HW_MODE)
78# define ME4600_AO_SW_WRAP_MODE ME4600_AO_WRAP_MODE
79
80# define ME4600_AO_INF_STOP_MODE 0x0
81# define ME4600_AO_ACQ_STOP_MODE 0x1
82# define ME4600_AO_SCAN_STOP_MODE 0x2
83
84# ifdef BOSCH //SPECIAL BUILD FOR BOSCH
85
86/* Bits for flags attribute. */
87# define ME4600_AO_FLAGS_BROKEN_PIPE 0x1
88# define ME4600_AO_FLAGS_SW_WRAP_MODE_0 0x2
89# define ME4600_AO_FLAGS_SW_WRAP_MODE_1 0x4
90# define ME4600_AO_FLAGS_SW_WRAP_MODE_MASK (ME4600_AO_FLAGS_SW_WRAP_MODE_0 | ME4600_AO_FLAGS_SW_WRAP_MODE_1)
91
92# define ME4600_AO_FLAGS_SW_WRAP_MODE_NONE 0x0
93# define ME4600_AO_FLAGS_SW_WRAP_MODE_INF 0x2
94# define ME4600_AO_FLAGS_SW_WRAP_MODE_FIN 0x4
95
96 /**
97 * @brief The ME-4000 analog output subdevice class.
98 */
99typedef struct me4600_ao_subdevice {
100 /* Inheritance */
101 me_subdevice_t base; /**< The subdevice base class. */
102
103 /* Attributes */
104 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
105 spinlock_t *preload_reg_lock; /**< Spin lock to protect #preload_reg from concurrent access. */
106 uint32_t *preload_flags;
107
108 unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */
109 me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. */
110 wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
111
112 int single_value; /**< Mirror of the value written in single mode. */
113
114 int volatile flags; /**< Flags used for storing SW wraparound setup and error signalling from ISR. */
115 unsigned int wrap_count; /**< The user defined wraparound cycle count. */
116 unsigned int wrap_remaining; /**< The wraparound cycle down counter used by a running conversion. */
117 unsigned int ao_idx; /**< The index of this analog output on this device. */
118 int fifo; /**< If set this device has a FIFO. */
119
120 int bosch_fw; /**< If set the bosch firmware is in PROM. */
121
122 /* Registers */
123 uint32_t ctrl_reg;
124 uint32_t status_reg;
125 uint32_t fifo_reg;
126 uint32_t single_reg;
127 uint32_t timer_reg;
128 uint32_t irq_status_reg;
129 uint32_t preload_reg;
130 uint32_t reg_base;
131} me4600_ao_subdevice_t;
132
133 /**
134 * @brief The constructor to generate a ME-4000 analog output subdevice instance for BOSCH project.
135 *
136 * @param reg_base The register base address of the device as returned by the PCI BIOS.
137 * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
138 * @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
139 * @param ao_idx Subdevice number.
140 * @param fifo Flag set if subdevice has hardware FIFO.
141 * @param irq IRQ number.
142 *
143 * @return Pointer to new instance on success.\n
144 * NULL on error.
145 */
146me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
147 spinlock_t * preload_reg_lock,
148 uint32_t * preload_flags,
149 int ao_idx, int fifo, int irq);
150
151# else //~BOSCH
152
153//ME4600_AO_FLAGS_BROKEN_PIPE is OBSOLETE => Now problems are reported in status.
154
155typedef enum ME4600_AO_STATUS {
156 ao_status_none = 0,
157 ao_status_single_configured,
158 ao_status_single_run_wait,
159 ao_status_single_run,
160 ao_status_single_end_wait,
161 ao_status_single_end,
162 ao_status_stream_configured,
163 ao_status_stream_run_wait,
164 ao_status_stream_run,
165 ao_status_stream_end_wait,
166 ao_status_stream_end,
167 ao_status_stream_fifo_error,
168 ao_status_stream_buffer_error,
169 ao_status_stream_error,
170 ao_status_last
171} ME4600_AO_STATUS;
172
173typedef struct me4600_ao_timeout {
174 unsigned long start_time;
175 unsigned long delay;
176} me4600_ao_timeout_t;
177
178 /**
179 * @brief The ME-4600 analog output subdevice class.
180 */
181typedef struct me4600_ao_subdevice {
182 /* Inheritance */
183 me_subdevice_t base; /**< The subdevice base class. */
184 unsigned int ao_idx; /**< The index of this analog output on this device. */
185
186 /* Attributes */
187 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
188 spinlock_t *preload_reg_lock; /**< Spin lock to protect preload_reg from concurrent access. */
189
190 uint32_t *preload_flags;
191
192 /* Hardware feautres */
193 unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */
194 int fifo; /**< If set this device has a FIFO. */
195 int bitpattern; /**< If set this device use bitpattern. */
196
197 int single_value; /**< Mirror of the output value in single mode. */
198 int single_value_in_fifo; /**< Mirror of the value written in single mode. */
199 uint32_t ctrl_trg; /**< Mirror of the trigger settings. */
200
201 volatile int mode; /**< Flags used for storing SW wraparound setup*/
202 int stop_mode; /**< The user defined stop condition flag. */
203 unsigned int start_mode;
204 unsigned int stop_count; /**< The user defined dates presentation end count. */
205 unsigned int stop_data_count; /**< The stop presentation count. */
206 unsigned int data_count; /**< The real presentation count. */
207 unsigned int preloaded_count; /**< The next data addres in buffer. <= for wraparound mode. */
208 int hardware_stop_delay; /**< The time that stop can take. This is only to not show hardware bug to user. */
209
210 volatile enum ME4600_AO_STATUS status; /**< The current stream status flag. */
211 me4600_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
212
213 /* Registers *//**< All registers are 32 bits long. */
214 unsigned long ctrl_reg;
215 unsigned long status_reg;
216 unsigned long fifo_reg;
217 unsigned long single_reg;
218 unsigned long timer_reg;
219 unsigned long irq_status_reg;
220 unsigned long preload_reg;
221 unsigned long reg_base;
222
223 /* Software buffer */
224 me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. 32 bit long */
225 wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
226
227 struct workqueue_struct *me4600_workqueue;
228#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
229 struct work_struct ao_control_task;
230#else
231 struct delayed_work ao_control_task;
232#endif
233
234 volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
235
236} me4600_ao_subdevice_t;
237
238 /**
239 * @brief The constructor to generate a ME-4600 analog output subdevice instance.
240 *
241 * @param reg_base The register base address of the device as returned by the PCI BIOS.
242 * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
243 * @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
244 * @param ao_idx Subdevice number.
245 * @param fifo Flag set if subdevice has hardware FIFO.
246 * @param irq IRQ number.
247 * @param me4600_wq Queue for asynchronous task (1 queue for all subdevice on 1 board).
248 *
249 * @return Pointer to new instance on success.\n
250 * NULL on error.
251 */
252me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
253 spinlock_t * preload_reg_lock,
254 uint32_t * preload_flags,
255 int ao_idx,
256 int fifo,
257 int irq,
258 struct workqueue_struct
259 *me4600_wq);
260
261# endif //BOSCH
262# endif //__KERNEL__
263#endif // ~_ME4600_AO_H_
diff --git a/drivers/staging/meilhaus/me4600_ao_reg.h b/drivers/staging/meilhaus/me4600_ao_reg.h
new file mode 100644
index 000000000000..f83d82ecd4bf
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_ao_reg.h
@@ -0,0 +1,113 @@
1/**
2 * @file me4600_ao_reg.h
3 *
4 * @brief ME-4000 analog output subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME4600_AO_REG_H_
28#define _ME4600_AO_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME4600_AO_00_CTRL_REG 0x00 // R/W
33#define ME4600_AO_00_STATUS_REG 0x04 // R/_
34#define ME4600_AO_00_FIFO_REG 0x08 // _/W
35#define ME4600_AO_00_SINGLE_REG 0x0C // R/W
36#define ME4600_AO_00_TIMER_REG 0x10 // _/W
37
38#define ME4600_AO_01_CTRL_REG 0x18 // R/W
39#define ME4600_AO_01_STATUS_REG 0x1C // R/_
40#define ME4600_AO_01_FIFO_REG 0x20 // _/W
41#define ME4600_AO_01_SINGLE_REG 0x24 // R/W
42#define ME4600_AO_01_TIMER_REG 0x28 // _/W
43
44#define ME4600_AO_02_CTRL_REG 0x30 // R/W
45#define ME4600_AO_02_STATUS_REG 0x34 // R/_
46#define ME4600_AO_02_FIFO_REG 0x38 // _/W
47#define ME4600_AO_02_SINGLE_REG 0x3C // R/W
48#define ME4600_AO_02_TIMER_REG 0x40 // _/W
49
50#define ME4600_AO_03_CTRL_REG 0x48 // R/W
51#define ME4600_AO_03_STATUS_REG 0x4C // R/_
52#define ME4600_AO_03_FIFO_REG 0x50 // _/W
53#define ME4600_AO_03_SINGLE_REG 0x54 // R/W
54#define ME4600_AO_03_TIMER_REG 0x58 // _/W
55
56#define ME4600_AO_DEMUX_ADJUST_REG 0xBC // -/W
57#define ME4600_AO_DEMUX_ADJUST_VALUE 0x4C
58
59#ifdef BOSCH
60# define ME4600_AO_BOSCH_REG 0xC4
61
62# define ME4600_AO_LOADSETREG_XX 0xB4 // R/W
63
64# define ME4600_AO_CTRL_BIT_MODE_0 0x001
65# define ME4600_AO_CTRL_BIT_MODE_1 0x002
66# define ME4600_AO_CTRL_MASK_MODE 0x003
67
68#else //~BOSCH
69
70#define ME4600_AO_SYNC_REG 0xB4 // R/W ///ME4600_AO_SYNC_REG <==> ME4600_AO_PRELOAD_REG <==> ME4600_AO_LOADSETREG_XX
71
72# define ME4600_AO_MODE_SINGLE 0x00000000
73# define ME4600_AO_MODE_WRAPAROUND 0x00000001
74# define ME4600_AO_MODE_CONTINUOUS 0x00000002
75# define ME4600_AO_CTRL_MODE_MASK (ME4600_AO_MODE_WRAPAROUND | ME4600_AO_MODE_CONTINUOUS)
76#endif //BOSCH
77
78#define ME4600_AO_CTRL_BIT_MODE_WRAPAROUND ME4600_AO_MODE_WRAPAROUND
79#define ME4600_AO_CTRL_BIT_MODE_CONTINOUS ME4600_AO_MODE_CONTINUOUS
80#define ME4600_AO_CTRL_BIT_STOP 0x00000004
81#define ME4600_AO_CTRL_BIT_ENABLE_FIFO 0x00000008
82#define ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG 0x00000010
83#define ME4600_AO_CTRL_BIT_EX_TRIG_EDGE 0x00000020
84#define ME4600_AO_CTRL_BIT_IMMEDIATE_STOP 0x00000080
85#define ME4600_AO_CTRL_BIT_ENABLE_DO 0x00000100
86#define ME4600_AO_CTRL_BIT_ENABLE_IRQ 0x00000200
87#define ME4600_AO_CTRL_BIT_RESET_IRQ 0x00000400
88#define ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH 0x00000800
89/*
90#define ME4600_AO_SYNC_HOLD_0 0x00000001
91#define ME4600_AO_SYNC_HOLD_1 0x00000002
92#define ME4600_AO_SYNC_HOLD_2 0x00000004
93#define ME4600_AO_SYNC_HOLD_3 0x00000008
94*/
95#define ME4600_AO_SYNC_HOLD 0x00000001
96
97/*
98#define ME4600_AO_SYNC_EXT_TRIG_0 0x00010000
99#define ME4600_AO_SYNC_EXT_TRIG_1 0x00020000
100#define ME4600_AO_SYNC_EXT_TRIG_2 0x00040000
101#define ME4600_AO_SYNC_EXT_TRIG_3 0x00080000
102*/
103#define ME4600_AO_SYNC_EXT_TRIG 0x00010000
104
105#define ME4600_AO_EXT_TRIG 0x80000000
106
107#define ME4600_AO_STATUS_BIT_FSM 0x00000001
108#define ME4600_AO_STATUS_BIT_FF 0x00000002
109#define ME4600_AO_STATUS_BIT_HF 0x00000004
110#define ME4600_AO_STATUS_BIT_EF 0x00000008
111
112#endif
113#endif
diff --git a/drivers/staging/meilhaus/me4600_device.c b/drivers/staging/meilhaus/me4600_device.c
new file mode 100644
index 000000000000..fa455844f4e3
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_device.c
@@ -0,0 +1,373 @@
1/**
2 * @file me4600_device.c
3 *
4 * @brief ME-4600 device class implementation.
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#ifndef MODULE
33# define MODULE
34#endif
35
36#include <linux/module.h>
37
38#include <linux/pci.h>
39#include <linux/slab.h>
40
41#include "meids.h"
42#include "meerror.h"
43#include "mecommon.h"
44#include "meinternal.h"
45
46#include "medebug.h"
47#include "medevice.h"
48#include "me4600_device.h"
49#include "meplx_reg.h"
50
51#include "mefirmware.h"
52
53#include "mesubdevice.h"
54#include "me4600_do.h"
55#include "me4600_di.h"
56#include "me4600_dio.h"
57#include "me8254.h"
58#include "me4600_ai.h"
59#include "me4600_ao.h"
60#include "me4600_ext_irq.h"
61
62/**
63 * @brief Global variable.
64 * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts).
65 */
66static struct workqueue_struct *me4600_workqueue;
67
68#ifdef BOSCH
69me_device_t *me4600_pci_constructor(struct pci_dev *pci_device, int me_bosch_fw)
70#else //~BOSCH
71me_device_t *me4600_pci_constructor(struct pci_dev *pci_device)
72#endif //BOSCH
73{
74 me4600_device_t *me4600_device;
75 me_subdevice_t *subdevice;
76 unsigned int version_idx;
77 int err;
78 int i;
79
80 PDEBUG("executed.\n");
81
82 // Allocate structure for device instance.
83 me4600_device = kmalloc(sizeof(me4600_device_t), GFP_KERNEL);
84
85 if (!me4600_device) {
86 PERROR("Cannot get memory for ME-4600 device instance.\n");
87 return NULL;
88 }
89
90 memset(me4600_device, 0, sizeof(me4600_device_t));
91
92 // Initialize base class structure.
93 err = me_device_pci_init((me_device_t *) me4600_device, pci_device);
94
95 if (err) {
96 kfree(me4600_device);
97 PERROR("Cannot initialize device base class.\n");
98 return NULL;
99 }
100 // Download the xilinx firmware.
101 if (me4600_device->base.info.pci.device_id == PCI_DEVICE_ID_MEILHAUS_ME4610) { //Jekyll <=> me4610
102 err =
103 me_xilinx_download(me4600_device->base.info.pci.
104 reg_bases[1],
105 me4600_device->base.info.pci.
106 reg_bases[5], &pci_device->dev,
107 "me4610.bin");
108 } else { // General me4600 firmware
109#ifdef BOSCH
110 err =
111 me_xilinx_download(me4600_device->base.info.pci.
112 reg_bases[1],
113 me4600_device->base.info.pci.
114 reg_bases[5], &pci_device->dev,
115 (me_bosch_fw) ? "me4600_bosch.bin" :
116 "me4600.bin");
117#else //~BOSCH
118 err =
119 me_xilinx_download(me4600_device->base.info.pci.
120 reg_bases[1],
121 me4600_device->base.info.pci.
122 reg_bases[5], &pci_device->dev,
123 "me4600.bin");
124#endif
125 }
126
127 if (err) {
128 me_device_deinit((me_device_t *) me4600_device);
129 kfree(me4600_device);
130 PERROR("Cannot download firmware.\n");
131 return NULL;
132 }
133 // Get the index in the device version information table.
134 version_idx =
135 me4600_versions_get_device_index(me4600_device->base.info.pci.
136 device_id);
137
138 // Initialize spin locks.
139 spin_lock_init(&me4600_device->preload_reg_lock);
140
141 me4600_device->preload_flags = 0;
142
143 spin_lock_init(&me4600_device->dio_lock);
144 spin_lock_init(&me4600_device->ai_ctrl_lock);
145 spin_lock_init(&me4600_device->ctr_ctrl_reg_lock);
146 spin_lock_init(&me4600_device->ctr_clk_src_reg_lock);
147
148 // Create digital input instances.
149 for (i = 0; i < me4600_versions[version_idx].di_subdevices; i++) {
150 subdevice =
151 (me_subdevice_t *) me4600_di_constructor(me4600_device->
152 base.info.pci.
153 reg_bases[2],
154 &me4600_device->
155 dio_lock);
156
157 if (!subdevice) {
158 me_device_deinit((me_device_t *) me4600_device);
159 kfree(me4600_device);
160 PERROR("Cannot get memory for subdevice.\n");
161 return NULL;
162 }
163
164 me_slist_add_subdevice_tail(&me4600_device->base.slist,
165 subdevice);
166 }
167
168 // Create digital output instances.
169 for (i = 0; i < me4600_versions[version_idx].do_subdevices; i++) {
170 subdevice =
171 (me_subdevice_t *) me4600_do_constructor(me4600_device->
172 base.info.pci.
173 reg_bases[2],
174 &me4600_device->
175 dio_lock);
176
177 if (!subdevice) {
178 me_device_deinit((me_device_t *) me4600_device);
179 kfree(me4600_device);
180 PERROR("Cannot get memory for subdevice.\n");
181 return NULL;
182 }
183
184 me_slist_add_subdevice_tail(&me4600_device->base.slist,
185 subdevice);
186 }
187
188 // Create digital input/output instances.
189 for (i = 0; i < me4600_versions[version_idx].dio_subdevices; i++) {
190 subdevice =
191 (me_subdevice_t *) me4600_dio_constructor(me4600_device->
192 base.info.pci.
193 reg_bases[2],
194 me4600_versions
195 [version_idx].
196 do_subdevices +
197 me4600_versions
198 [version_idx].
199 di_subdevices + i,
200 &me4600_device->
201 dio_lock);
202
203 if (!subdevice) {
204 me_device_deinit((me_device_t *) me4600_device);
205 kfree(me4600_device);
206 PERROR("Cannot get memory for subdevice.\n");
207 return NULL;
208 }
209
210 me_slist_add_subdevice_tail(&me4600_device->base.slist,
211 subdevice);
212 }
213
214 // Create analog input instances.
215 for (i = 0; i < me4600_versions[version_idx].ai_subdevices; i++) {
216 subdevice =
217 (me_subdevice_t *) me4600_ai_constructor(me4600_device->
218 base.info.pci.
219 reg_bases[2],
220 me4600_versions
221 [version_idx].
222 ai_channels,
223 me4600_versions
224 [version_idx].
225 ai_ranges,
226 me4600_versions
227 [version_idx].
228 ai_isolated,
229 me4600_versions
230 [version_idx].
231 ai_sh,
232 me4600_device->
233 base.irq,
234 &me4600_device->
235 ai_ctrl_lock,
236 me4600_workqueue);
237
238 if (!subdevice) {
239 me_device_deinit((me_device_t *) me4600_device);
240 kfree(me4600_device);
241 PERROR("Cannot get memory for subdevice.\n");
242 return NULL;
243 }
244
245 me_slist_add_subdevice_tail(&me4600_device->base.slist,
246 subdevice);
247 }
248
249 // Create analog output instances.
250 for (i = 0; i < me4600_versions[version_idx].ao_subdevices; i++) {
251#ifdef BOSCH
252 subdevice =
253 (me_subdevice_t *) me4600_ao_constructor(me4600_device->
254 base.info.pci.
255 reg_bases[2],
256 &me4600_device->
257 preload_reg_lock,
258 &me4600_device->
259 preload_flags, i,
260 me4600_versions
261 [version_idx].
262 ao_fifo,
263 me4600_device->
264 base.irq);
265#else //~BOSCH
266 subdevice =
267 (me_subdevice_t *) me4600_ao_constructor(me4600_device->
268 base.info.pci.
269 reg_bases[2],
270 &me4600_device->
271 preload_reg_lock,
272 &me4600_device->
273 preload_flags, i,
274 me4600_versions
275 [version_idx].
276 ao_fifo,
277 me4600_device->
278 base.irq,
279 me4600_workqueue);
280#endif
281
282 if (!subdevice) {
283 me_device_deinit((me_device_t *) me4600_device);
284 kfree(me4600_device);
285 PERROR("Cannot get memory for subdevice.\n");
286 return NULL;
287 }
288
289 me_slist_add_subdevice_tail(&me4600_device->base.slist,
290 subdevice);
291 }
292
293 // Create counter instances.
294 for (i = 0; i < me4600_versions[version_idx].ctr_subdevices; i++) {
295 subdevice =
296 (me_subdevice_t *) me8254_constructor(me4600_device->base.
297 info.pci.device_id,
298 me4600_device->base.
299 info.pci.reg_bases[3],
300 0, i,
301 &me4600_device->
302 ctr_ctrl_reg_lock,
303 &me4600_device->
304 ctr_clk_src_reg_lock);
305
306 if (!subdevice) {
307 me_device_deinit((me_device_t *) me4600_device);
308 kfree(me4600_device);
309 PERROR("Cannot get memory for subdevice.\n");
310 return NULL;
311 }
312
313 me_slist_add_subdevice_tail(&me4600_device->base.slist,
314 subdevice);
315 }
316
317 // Create external interrupt instances.
318 for (i = 0; i < me4600_versions[version_idx].ext_irq_subdevices; i++) {
319 subdevice =
320 (me_subdevice_t *)
321 me4600_ext_irq_constructor(me4600_device->base.info.pci.
322 reg_bases[2],
323 me4600_device->base.irq,
324 &me4600_device->ai_ctrl_lock);
325
326 if (!subdevice) {
327 me_device_deinit((me_device_t *) me4600_device);
328 kfree(me4600_device);
329 PERROR("Cannot get memory for subdevice.\n");
330 return NULL;
331 }
332
333 me_slist_add_subdevice_tail(&me4600_device->base.slist,
334 subdevice);
335 }
336
337 return (me_device_t *) me4600_device;
338}
339
340// Init and exit of module.
341
342static int __init me4600_init(void)
343{
344 PDEBUG("executed.\n");
345
346#ifndef BOSCH
347 me4600_workqueue = create_singlethread_workqueue("me4600");
348#endif
349 return 0;
350}
351
352static void __exit me4600_exit(void)
353{
354 PDEBUG("executed.\n");
355
356#ifndef BOSCH
357 flush_workqueue(me4600_workqueue);
358 destroy_workqueue(me4600_workqueue);
359#endif
360}
361
362module_init(me4600_init);
363module_exit(me4600_exit);
364
365// Administrative stuff for modinfo.
366MODULE_AUTHOR
367 ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
368MODULE_DESCRIPTION("Device Driver Module for ME-46xx Devices");
369MODULE_SUPPORTED_DEVICE("Meilhaus ME-46xx Devices");
370MODULE_LICENSE("GPL");
371
372// Export the constructor.
373EXPORT_SYMBOL(me4600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me4600_device.h b/drivers/staging/meilhaus/me4600_device.h
new file mode 100644
index 000000000000..fa812d4cc6dc
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_device.h
@@ -0,0 +1,151 @@
1/**
2 * @file me4600_device.h
3 *
4 * @brief ME-4600 device class.
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 _ME4600_DEVICE_H
29#define _ME4600_DEVICE_H
30
31#include <linux/pci.h>
32#include <linux/spinlock.h>
33
34#include "medevice.h"
35
36#ifdef __KERNEL__
37
38/**
39 * @brief Structure holding ME-4600 device capabilities.
40 */
41typedef struct me4600_version {
42 uint16_t device_id;
43 unsigned int do_subdevices;
44 unsigned int di_subdevices;
45 unsigned int dio_subdevices;
46 unsigned int ctr_subdevices;
47 unsigned int ai_subdevices;
48 unsigned int ai_channels;
49 unsigned int ai_ranges;
50 unsigned int ai_isolated;
51 unsigned int ai_sh;
52 unsigned int ao_subdevices;
53 unsigned int ao_fifo; //How many devices have FIFO
54 unsigned int ext_irq_subdevices;
55} me4600_version_t;
56
57/**
58 * @brief ME-4600 device capabilities.
59 */
60static me4600_version_t me4600_versions[] = {
61 {PCI_DEVICE_ID_MEILHAUS_ME4610, 0, 0, 4, 3, 1, 16, 1, 0, 0, 0, 0, 1},
62
63 {PCI_DEVICE_ID_MEILHAUS_ME4650, 0, 0, 4, 0, 1, 16, 4, 0, 0, 0, 0, 1},
64
65 {PCI_DEVICE_ID_MEILHAUS_ME4660, 0, 0, 4, 3, 1, 16, 4, 0, 0, 2, 0, 1},
66 {PCI_DEVICE_ID_MEILHAUS_ME4660I, 1, 1, 2, 3, 1, 16, 4, 1, 0, 2, 0, 1},
67 {PCI_DEVICE_ID_MEILHAUS_ME4660S, 0, 0, 4, 3, 1, 16, 4, 0, 1, 2, 0, 1},
68 {PCI_DEVICE_ID_MEILHAUS_ME4660IS, 1, 1, 2, 3, 1, 16, 4, 1, 1, 2, 0, 1},
69
70 {PCI_DEVICE_ID_MEILHAUS_ME4670, 0, 0, 4, 3, 1, 32, 4, 0, 0, 4, 0, 1},
71 {PCI_DEVICE_ID_MEILHAUS_ME4670I, 1, 1, 2, 3, 1, 32, 4, 1, 0, 4, 0, 1},
72 {PCI_DEVICE_ID_MEILHAUS_ME4670S, 0, 0, 4, 3, 1, 32, 4, 0, 1, 4, 0, 1},
73 {PCI_DEVICE_ID_MEILHAUS_ME4670IS, 1, 1, 2, 3, 1, 32, 4, 1, 1, 4, 0, 1},
74
75 {PCI_DEVICE_ID_MEILHAUS_ME4680, 0, 0, 4, 3, 1, 32, 4, 0, 0, 4, 4, 1},
76 {PCI_DEVICE_ID_MEILHAUS_ME4680I, 1, 1, 2, 3, 1, 32, 4, 1, 0, 4, 4, 1},
77 {PCI_DEVICE_ID_MEILHAUS_ME4680S, 0, 0, 4, 3, 1, 32, 4, 0, 1, 4, 4, 1},
78 {PCI_DEVICE_ID_MEILHAUS_ME4680IS, 1, 1, 2, 3, 1, 32, 4, 1, 1, 4, 4, 1},
79
80 {0},
81};
82
83#define ME4600_DEVICE_VERSIONS (sizeof(me4600_versions) / sizeof(me4600_version_t) - 1) /**< Returns the number of entries in #me4600_versions. */
84
85/**
86 * @brief Returns the index of the device entry in #me4600_versions.
87 *
88 * @param device_id The PCI device id of the device to query.
89 * @return The index of the device in #me4600_versions.
90 */
91static inline unsigned int me4600_versions_get_device_index(uint16_t device_id)
92{
93 unsigned int i;
94 for (i = 0; i < ME4600_DEVICE_VERSIONS; i++)
95 if (me4600_versions[i].device_id == device_id)
96 break;
97 return i;
98}
99
100/**
101 * @brief The ME-4600 device class structure.
102 */
103typedef struct me4600_device {
104 me_device_t base; /**< The Meilhaus device base class. */
105
106 /* Child class attributes. */
107 spinlock_t preload_reg_lock; /**< Guards the preload register of the anaolog output devices. */
108 unsigned int preload_flags; /**< Used in conjunction with #preload_reg_lock. */
109 spinlock_t dio_lock; /**< Locks the control register of the digital input/output subdevices. */
110 spinlock_t ai_ctrl_lock; /**< Locks the control register of the analog input subdevice. */
111 spinlock_t ctr_ctrl_reg_lock; /**< Locks the counter control register. */
112 spinlock_t ctr_clk_src_reg_lock; /**< Not used on this device but needed for the me8254 subdevice constructor call. */
113} me4600_device_t;
114
115/**
116 * @brief The ME-4600 device class constructor.
117 *
118 * @param pci_device The pci device structure given by the PCI subsystem.
119 * @param me_bosch_fw If set the device shall use the bosch firmware. (Only for special BOSCH build)
120 *
121 * @return On succes a new ME-4600 device instance. \n
122 * NULL on error.
123 */
124
125#ifdef BOSCH
126/**
127 * @brief The ME-4600 device class constructor.
128 *
129 * @param pci_device The pci device structure given by the PCI subsystem.
130 * @param me_bosch_fw If set the device shall use the bosch firmware.
131 *
132 * @return On succes a new ME-4600 device instance. \n
133 * NULL on error.
134 */
135me_device_t *me4600_pci_constructor(struct pci_dev *pci_device, int me_bosch_fw)
136 __attribute__ ((weak));
137#else //~BOSCH
138/**
139 * @brief The ME-4600 device class constructor.
140 *
141 * @param pci_device The pci device structure given by the PCI subsystem.
142 *
143 * @return On succes a new ME-4600 device instance. \n
144 * NULL on error.
145 */
146me_device_t *me4600_pci_constructor(struct pci_dev *pci_device)
147 __attribute__ ((weak));
148#endif
149
150#endif
151#endif
diff --git a/drivers/staging/meilhaus/me4600_di.c b/drivers/staging/meilhaus/me4600_di.c
new file mode 100644
index 000000000000..7e3c9f4d2df2
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_di.c
@@ -0,0 +1,256 @@
1/**
2 * @file me4600_di.c
3 *
4 * @brief ME-4000 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45
46#include "medebug.h"
47#include "me4600_dio_reg.h"
48#include "me4600_di.h"
49
50/*
51 * Defines
52 */
53
54/*
55 * Functions
56 */
57
58static int me4600_di_io_reset_subdevice(struct me_subdevice *subdevice,
59 struct file *filep, int flags)
60{
61 me4600_di_subdevice_t *instance;
62 uint32_t mode;
63
64 PDEBUG("executed.\n");
65
66 instance = (me4600_di_subdevice_t *) subdevice;
67
68 if (flags) {
69 PERROR("Invalid flag specified.\n");
70 return ME_ERRNO_INVALID_FLAGS;
71 }
72
73 ME_SUBDEVICE_ENTER;
74
75 spin_lock(&instance->subdevice_lock);
76 spin_lock(instance->ctrl_reg_lock);
77 mode = inl(instance->ctrl_reg);
78 mode &= ~(ME4600_DIO_CTRL_BIT_MODE_2 | ME4600_DIO_CTRL_BIT_MODE_3); //0xFFF3
79 outl(mode, instance->ctrl_reg);
80 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
81 instance->ctrl_reg - instance->reg_base, mode);
82 spin_unlock(instance->ctrl_reg_lock);
83
84 outl(0, instance->port_reg);
85 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
86 instance->port_reg - instance->reg_base, 0);
87 spin_unlock(&instance->subdevice_lock);
88
89 ME_SUBDEVICE_EXIT;
90
91 return ME_ERRNO_SUCCESS;
92}
93
94static int me4600_di_io_single_config(me_subdevice_t * subdevice,
95 struct file *filep,
96 int channel,
97 int single_config,
98 int ref,
99 int trig_chan,
100 int trig_type, int trig_edge, int flags)
101{
102 int err = ME_ERRNO_SUCCESS;
103 me4600_di_subdevice_t *instance;
104
105 PDEBUG("executed.\n");
106
107 instance = (me4600_di_subdevice_t *) subdevice;
108
109 ME_SUBDEVICE_ENTER;
110
111 switch (flags) {
112 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
113 case ME_IO_SINGLE_CONFIG_DIO_BYTE:
114 if (channel == 0) {
115 if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
116 } else {
117 PERROR("Invalid port direction specified.\n");
118 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
119 }
120 } else {
121 PERROR("Invalid channel number.\n");
122 err = ME_ERRNO_INVALID_CHANNEL;
123 }
124 break;
125
126 default:
127 PERROR("Invalid flags specified.\n");
128 err = ME_ERRNO_INVALID_FLAGS;
129 }
130
131 ME_SUBDEVICE_EXIT;
132
133 return err;
134}
135
136static int me4600_di_io_single_read(me_subdevice_t * subdevice,
137 struct file *filep,
138 int channel,
139 int *value, int time_out, int flags)
140{
141 me4600_di_subdevice_t *instance;
142 int err = ME_ERRNO_SUCCESS;
143
144 PDEBUG("executed.\n");
145
146 instance = (me4600_di_subdevice_t *) subdevice;
147
148 ME_SUBDEVICE_ENTER;
149
150 switch (flags) {
151 case ME_IO_SINGLE_TYPE_DIO_BIT:
152 if ((channel >= 0) && (channel < 8)) {
153 *value = inl(instance->port_reg) & (0x1 << channel);
154 } else {
155 PERROR("Invalid bit number specified.\n");
156 err = ME_ERRNO_INVALID_CHANNEL;
157 }
158 break;
159
160 case ME_IO_SINGLE_NO_FLAGS:
161 case ME_IO_SINGLE_TYPE_DIO_BYTE:
162 if (channel == 0) {
163 *value = inl(instance->port_reg) & 0xFF;
164 } else {
165 PERROR("Invalid byte number specified.\n");
166 err = ME_ERRNO_INVALID_CHANNEL;
167 }
168 break;
169
170 default:
171 PERROR("Invalid flags specified.\n");
172 err = ME_ERRNO_INVALID_FLAGS;
173 }
174
175 ME_SUBDEVICE_EXIT;
176
177 return err;
178}
179
180static int me4600_di_query_number_channels(me_subdevice_t * subdevice,
181 int *number)
182{
183 PDEBUG("executed.\n");
184 *number = 8;
185 return ME_ERRNO_SUCCESS;
186}
187
188static int me4600_di_query_subdevice_type(me_subdevice_t * subdevice,
189 int *type, int *subtype)
190{
191 PDEBUG("executed.\n");
192 *type = ME_TYPE_DI;
193 *subtype = ME_SUBTYPE_SINGLE;
194 return ME_ERRNO_SUCCESS;
195}
196
197static int me4600_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
198{
199 PDEBUG("executed.\n");
200 *caps = 0;
201 return ME_ERRNO_SUCCESS;
202}
203
204me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base,
205 spinlock_t * ctrl_reg_lock)
206{
207 me4600_di_subdevice_t *subdevice;
208 int err;
209
210 PDEBUG("executed.\n");
211
212 /* Allocate memory for subdevice instance */
213 subdevice = kmalloc(sizeof(me4600_di_subdevice_t), GFP_KERNEL);
214
215 if (!subdevice) {
216 PERROR("Cannot get memory for subdevice instance.\n");
217 return NULL;
218 }
219
220 memset(subdevice, 0, sizeof(me4600_di_subdevice_t));
221
222 /* Initialize subdevice base class */
223 err = me_subdevice_init(&subdevice->base);
224
225 if (err) {
226 PERROR("Cannot initialize subdevice base class instance.\n");
227 kfree(subdevice);
228 return NULL;
229 }
230 // Initialize spin locks.
231 spin_lock_init(&subdevice->subdevice_lock);
232
233 subdevice->ctrl_reg_lock = ctrl_reg_lock;
234
235 /* Save the subdevice index */
236 subdevice->port_reg = reg_base + ME4600_DIO_PORT_1_REG;
237 subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
238#ifdef MEDEBUG_DEBUG_REG
239 subdevice->reg_base = reg_base;
240#endif
241
242 /* Overload base class methods. */
243 subdevice->base.me_subdevice_io_reset_subdevice =
244 me4600_di_io_reset_subdevice;
245 subdevice->base.me_subdevice_io_single_config =
246 me4600_di_io_single_config;
247 subdevice->base.me_subdevice_io_single_read = me4600_di_io_single_read;
248 subdevice->base.me_subdevice_query_number_channels =
249 me4600_di_query_number_channels;
250 subdevice->base.me_subdevice_query_subdevice_type =
251 me4600_di_query_subdevice_type;
252 subdevice->base.me_subdevice_query_subdevice_caps =
253 me4600_di_query_subdevice_caps;
254
255 return subdevice;
256}
diff --git a/drivers/staging/meilhaus/me4600_di.h b/drivers/staging/meilhaus/me4600_di.h
new file mode 100644
index 000000000000..ec8b175755be
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_di.h
@@ -0,0 +1,64 @@
1/**
2 * @file me4600_di.h
3 *
4 * @brief ME-4000 digital input subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME4600_DI_H_
28#define _ME4600_DI_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me4600_di_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
44
45 unsigned long port_reg; /**< Register holding the port status. */
46 unsigned long ctrl_reg; /**< Register to configure the port direction. */
47#ifdef MEDEBUG_DEBUG_REG
48 unsigned long reg_base;
49#endif
50} me4600_di_subdevice_t;
51
52/**
53 * @brief The constructor to generate a ME-4000 digital input subdevice instance.
54 *
55 * @param reg_base The register base address of the device as returned by the PCI BIOS.
56 *
57 * @return Pointer to new instance on success.\n
58 * NULL on error.
59 */
60me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base,
61 spinlock_t * ctrl_reg_lock);
62
63#endif
64#endif
diff --git a/drivers/staging/meilhaus/me4600_dio.c b/drivers/staging/meilhaus/me4600_dio.c
new file mode 100644
index 000000000000..0af95d1a8f5d
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_dio.c
@@ -0,0 +1,510 @@
1/**
2 * @file me4600_dio.c
3 *
4 * @brief ME-4000 digital input/output 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45
46#include "medebug.h"
47#include "me4600_dio_reg.h"
48#include "me4600_dio.h"
49
50/*
51 * Defines
52 */
53
54/*
55 * Functions
56 */
57
58static int me4600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
59 struct file *filep, int flags)
60{
61 me4600_dio_subdevice_t *instance;
62 uint32_t mode;
63
64 PDEBUG("executed.\n");
65
66 instance = (me4600_dio_subdevice_t *) subdevice;
67
68 if (flags) {
69 PERROR("Invalid flag specified.\n");
70 return ME_ERRNO_INVALID_FLAGS;
71 }
72
73 ME_SUBDEVICE_ENTER;
74
75 /* Set port to input mode */
76 spin_lock(&instance->subdevice_lock);
77 spin_lock(instance->ctrl_reg_lock);
78 mode = inl(instance->ctrl_reg);
79 mode &=
80 ~((ME4600_DIO_CTRL_BIT_MODE_0 | ME4600_DIO_CTRL_BIT_MODE_1) <<
81 (instance->dio_idx * 2));
82 outl(mode, instance->ctrl_reg);
83 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
84 instance->ctrl_reg - instance->reg_base, mode);
85 spin_unlock(instance->ctrl_reg_lock);
86
87 outl(0, instance->port_reg);
88 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
89 instance->port_reg - instance->reg_base, 0);
90 spin_unlock(&instance->subdevice_lock);
91
92 ME_SUBDEVICE_EXIT;
93
94 return ME_ERRNO_SUCCESS;
95}
96
97static int me4600_dio_io_single_config(me_subdevice_t * subdevice,
98 struct file *filep,
99 int channel,
100 int single_config,
101 int ref,
102 int trig_chan,
103 int trig_type, int trig_edge, int flags)
104{
105 me4600_dio_subdevice_t *instance;
106 int err = ME_ERRNO_SUCCESS;
107 uint32_t mode;
108 uint32_t size =
109 flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
110 | ME_IO_SINGLE_CONFIG_DIO_WORD |
111 ME_IO_SINGLE_CONFIG_DIO_DWORD);
112 uint32_t mask;
113
114 PDEBUG("executed.\n");
115
116 instance = (me4600_dio_subdevice_t *) subdevice;
117
118 ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
119 spin_lock(instance->ctrl_reg_lock);
120 mode = inl(instance->ctrl_reg);
121 switch (size) {
122 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
123 case ME_IO_SINGLE_CONFIG_DIO_BYTE:
124 if (channel == 0) {
125 if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
126 mode &=
127 ~((ME4600_DIO_CTRL_BIT_MODE_0 |
128 ME4600_DIO_CTRL_BIT_MODE_1) <<
129 (instance->dio_idx * 2));
130 } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
131 mode &=
132 ~((ME4600_DIO_CTRL_BIT_MODE_0 |
133 ME4600_DIO_CTRL_BIT_MODE_1) <<
134 (instance->dio_idx * 2));
135 mode |=
136 ME4600_DIO_CTRL_BIT_MODE_0 << (instance->
137 dio_idx * 2);
138 } else if (single_config == ME_SINGLE_CONFIG_DIO_MUX32M) {
139 mask =
140 (ME4600_DIO_CTRL_BIT_MODE_0 |
141 ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
142 dio_idx *
143 2);
144 mask |=
145 ME4600_DIO_CTRL_BIT_FUNCTION_0 |
146 ME4600_DIO_CTRL_BIT_FUNCTION_1;
147 mask |=
148 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
149 instance->dio_idx;
150 mode &= ~mask;
151
152 if (ref == ME_REF_DIO_FIFO_LOW) {
153 mode |=
154 (ME4600_DIO_CTRL_BIT_MODE_0 |
155 ME4600_DIO_CTRL_BIT_MODE_1) <<
156 (instance->dio_idx * 2);
157 mode |= ME4600_DIO_CTRL_BIT_FUNCTION_1;
158 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
159 mode |=
160 (ME4600_DIO_CTRL_BIT_MODE_0 |
161 ME4600_DIO_CTRL_BIT_MODE_1) <<
162 (instance->dio_idx * 2);
163 mode |= ME4600_DIO_CTRL_BIT_FUNCTION_1;
164 mode |=
165 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
166 instance->dio_idx;
167 } else {
168 PERROR
169 ("Invalid port reference specified.\n");
170 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
171 }
172 } else if (single_config ==
173 ME_SINGLE_CONFIG_DIO_DEMUX32) {
174 mask =
175 (ME4600_DIO_CTRL_BIT_MODE_0 |
176 ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
177 dio_idx *
178 2);
179 mask |=
180 ME4600_DIO_CTRL_BIT_FUNCTION_0 |
181 ME4600_DIO_CTRL_BIT_FUNCTION_1;
182 mask |=
183 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
184 instance->dio_idx;
185 mode &= ~mask;
186
187 if (ref == ME_REF_DIO_FIFO_LOW) {
188 mode |=
189 (ME4600_DIO_CTRL_BIT_MODE_0 |
190 ME4600_DIO_CTRL_BIT_MODE_1) <<
191 (instance->dio_idx * 2);
192 mode |= ME4600_DIO_CTRL_BIT_FUNCTION_0;
193 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
194 mode |=
195 (ME4600_DIO_CTRL_BIT_MODE_0 |
196 ME4600_DIO_CTRL_BIT_MODE_1) <<
197 (instance->dio_idx * 2);
198 mode |= ME4600_DIO_CTRL_BIT_FUNCTION_0;
199 mode |=
200 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
201 instance->dio_idx;
202 } else {
203 PERROR
204 ("Invalid port reference specified.\n");
205 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
206 }
207 } else if (single_config ==
208 ME_SINGLE_CONFIG_DIO_BIT_PATTERN) {
209 mask =
210 (ME4600_DIO_CTRL_BIT_MODE_0 |
211 ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
212 dio_idx *
213 2);
214 mask |=
215 ME4600_DIO_CTRL_BIT_FUNCTION_0 |
216 ME4600_DIO_CTRL_BIT_FUNCTION_1;
217 mask |=
218 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
219 instance->dio_idx;
220 mode &= ~mask;
221
222 if (ref == ME_REF_DIO_FIFO_LOW) {
223 mode |=
224 (ME4600_DIO_CTRL_BIT_MODE_0 |
225 ME4600_DIO_CTRL_BIT_MODE_1) <<
226 (instance->dio_idx * 2);
227 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
228 mode |=
229 (ME4600_DIO_CTRL_BIT_MODE_0 |
230 ME4600_DIO_CTRL_BIT_MODE_1) <<
231 (instance->dio_idx * 2);
232 mode |=
233 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
234 instance->dio_idx;
235 } else {
236 PERROR
237 ("Invalid port reference specified.\n");
238 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
239 }
240 } else {
241 PERROR
242 ("Invalid port configuration specified.\n");
243 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
244 }
245 } else {
246 PERROR("Invalid channel number.\n");
247 err = ME_ERRNO_INVALID_CHANNEL;
248 }
249
250 break;
251
252 default:
253 PERROR("Invalid flags.\n");
254 err = ME_ERRNO_INVALID_FLAGS;
255 }
256
257 if (!err) {
258 outl(mode, instance->ctrl_reg);
259 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
260 instance->reg_base,
261 instance->ctrl_reg - instance->reg_base, mode);
262 }
263 spin_unlock(instance->ctrl_reg_lock);
264 spin_unlock(&instance->subdevice_lock);
265
266 ME_SUBDEVICE_EXIT;
267
268 return err;
269}
270
271static int me4600_dio_io_single_read(me_subdevice_t * subdevice,
272 struct file *filep,
273 int channel,
274 int *value, int time_out, int flags)
275{
276 me4600_dio_subdevice_t *instance;
277 int err = ME_ERRNO_SUCCESS;
278 uint32_t mode;
279
280 PDEBUG("executed.\n");
281
282 instance = (me4600_dio_subdevice_t *) subdevice;
283
284 ME_SUBDEVICE_ENTER;
285
286 spin_lock(&instance->subdevice_lock);
287 spin_lock(instance->ctrl_reg_lock);
288 switch (flags) {
289 case ME_IO_SINGLE_TYPE_DIO_BIT:
290 if ((channel >= 0) && (channel < 8)) {
291 mode =
292 inl(instance->
293 ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
294 ME4600_DIO_CTRL_BIT_MODE_1) <<
295 (instance->dio_idx * 2));
296 if ((mode ==
297 (ME4600_DIO_CTRL_BIT_MODE_0 <<
298 (instance->dio_idx * 2))) || !mode) {
299 *value =
300 inl(instance->port_reg) & (0x1 << channel);
301 } else {
302 PERROR("Port not in output or input mode.\n");
303 err = ME_ERRNO_PREVIOUS_CONFIG;
304 }
305 } else {
306 PERROR("Invalid bit number specified.\n");
307 err = ME_ERRNO_INVALID_CHANNEL;
308 }
309 break;
310
311 case ME_IO_SINGLE_NO_FLAGS:
312 case ME_IO_SINGLE_TYPE_DIO_BYTE:
313 if (channel == 0) {
314 mode =
315 inl(instance->
316 ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
317 ME4600_DIO_CTRL_BIT_MODE_1) <<
318 (instance->dio_idx * 2));
319 if ((mode ==
320 (ME4600_DIO_CTRL_BIT_MODE_0 <<
321 (instance->dio_idx * 2))) || !mode) {
322 *value = inl(instance->port_reg) & 0xFF;
323 } else {
324 PERROR("Port not in output or input mode.\n");
325 err = ME_ERRNO_PREVIOUS_CONFIG;
326 }
327 } else {
328 PERROR("Invalid byte number specified.\n");
329 err = ME_ERRNO_INVALID_CHANNEL;
330 }
331 break;
332
333 default:
334 PERROR("Invalid flags specified.\n");
335 err = ME_ERRNO_INVALID_FLAGS;
336 }
337 spin_unlock(instance->ctrl_reg_lock);
338 spin_unlock(&instance->subdevice_lock);
339
340 ME_SUBDEVICE_EXIT;
341
342 return err;
343}
344
345static int me4600_dio_io_single_write(me_subdevice_t * subdevice,
346 struct file *filep,
347 int channel,
348 int value, int time_out, int flags)
349{
350 me4600_dio_subdevice_t *instance;
351 int err = ME_ERRNO_SUCCESS;
352 uint32_t mode;
353 uint32_t byte;
354
355 PDEBUG("executed.\n");
356
357 instance = (me4600_dio_subdevice_t *) subdevice;
358
359 ME_SUBDEVICE_ENTER;
360
361 spin_lock(&instance->subdevice_lock);
362 spin_lock(instance->ctrl_reg_lock);
363 switch (flags) {
364 case ME_IO_SINGLE_TYPE_DIO_BIT:
365 if ((channel >= 0) && (channel < 8)) {
366 mode =
367 inl(instance->
368 ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
369 ME4600_DIO_CTRL_BIT_MODE_1) <<
370 (instance->dio_idx * 2));
371
372 if (mode ==
373 (ME4600_DIO_CTRL_BIT_MODE_0 <<
374 (instance->dio_idx * 2))) {
375 byte = inl(instance->port_reg) & 0xFF;
376
377 if (value)
378 byte |= 0x1 << channel;
379 else
380 byte &= ~(0x1 << channel);
381
382 outl(byte, instance->port_reg);
383 } else {
384 PERROR("Port not in output or input mode.\n");
385 err = ME_ERRNO_PREVIOUS_CONFIG;
386 }
387 } else {
388 PERROR("Invalid bit number specified.\n");
389 err = ME_ERRNO_INVALID_CHANNEL;
390 }
391 break;
392
393 case ME_IO_SINGLE_NO_FLAGS:
394 case ME_IO_SINGLE_TYPE_DIO_BYTE:
395 if (channel == 0) {
396 mode =
397 inl(instance->
398 ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
399 ME4600_DIO_CTRL_BIT_MODE_1) <<
400 (instance->dio_idx * 2));
401
402 if (mode ==
403 (ME4600_DIO_CTRL_BIT_MODE_0 <<
404 (instance->dio_idx * 2))) {
405 outl(value, instance->port_reg);
406 } else {
407 PERROR("Port not in output or input mode.\n");
408 err = ME_ERRNO_PREVIOUS_CONFIG;
409 }
410 } else {
411 PERROR("Invalid byte number specified.\n");
412 err = ME_ERRNO_INVALID_CHANNEL;
413 }
414 break;
415
416 default:
417 PERROR("Invalid flags specified.\n");
418 err = ME_ERRNO_INVALID_FLAGS;
419 }
420 spin_unlock(instance->ctrl_reg_lock);
421 spin_unlock(&instance->subdevice_lock);
422
423 ME_SUBDEVICE_EXIT;
424
425 return err;
426}
427
428static int me4600_dio_query_number_channels(me_subdevice_t * subdevice,
429 int *number)
430{
431 PDEBUG("executed.\n");
432 *number = 8;
433 return ME_ERRNO_SUCCESS;
434}
435
436static int me4600_dio_query_subdevice_type(me_subdevice_t * subdevice,
437 int *type, int *subtype)
438{
439 PDEBUG("executed.\n");
440 *type = ME_TYPE_DIO;
441 *subtype = ME_SUBTYPE_SINGLE;
442 return ME_ERRNO_SUCCESS;
443}
444
445static int me4600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
446 int *caps)
447{
448 PDEBUG("executed.\n");
449 *caps = ME_CAPS_DIO_DIR_BYTE;
450 return ME_ERRNO_SUCCESS;
451}
452
453me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base,
454 unsigned int dio_idx,
455 spinlock_t * ctrl_reg_lock)
456{
457 me4600_dio_subdevice_t *subdevice;
458 int err;
459
460 PDEBUG("executed.\n");
461
462 /* Allocate memory for subdevice instance */
463 subdevice = kmalloc(sizeof(me4600_dio_subdevice_t), GFP_KERNEL);
464
465 if (!subdevice) {
466 PERROR("Cannot get memory for subdevice instance.\n");
467 return NULL;
468 }
469
470 memset(subdevice, 0, sizeof(me4600_dio_subdevice_t));
471
472 /* Initialize subdevice base class */
473 err = me_subdevice_init(&subdevice->base);
474
475 if (err) {
476 PERROR("Cannot initialize subdevice base class instance.\n");
477 kfree(subdevice);
478 return NULL;
479 }
480 // Initialize spin locks.
481 spin_lock_init(&subdevice->subdevice_lock);
482 subdevice->ctrl_reg_lock = ctrl_reg_lock;
483
484 /* Save digital i/o index */
485 subdevice->dio_idx = dio_idx;
486
487 /* Save the subdevice index */
488 subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
489 subdevice->port_reg = reg_base + ME4600_DIO_PORT_REG + (dio_idx * 4);
490#ifdef MEDEBUG_DEBUG_REG
491 subdevice->reg_base = reg_base;
492#endif
493
494 /* Overload base class methods. */
495 subdevice->base.me_subdevice_io_reset_subdevice =
496 me4600_dio_io_reset_subdevice;
497 subdevice->base.me_subdevice_io_single_config =
498 me4600_dio_io_single_config;
499 subdevice->base.me_subdevice_io_single_read = me4600_dio_io_single_read;
500 subdevice->base.me_subdevice_io_single_write =
501 me4600_dio_io_single_write;
502 subdevice->base.me_subdevice_query_number_channels =
503 me4600_dio_query_number_channels;
504 subdevice->base.me_subdevice_query_subdevice_type =
505 me4600_dio_query_subdevice_type;
506 subdevice->base.me_subdevice_query_subdevice_caps =
507 me4600_dio_query_subdevice_caps;
508
509 return subdevice;
510}
diff --git a/drivers/staging/meilhaus/me4600_dio.h b/drivers/staging/meilhaus/me4600_dio.h
new file mode 100644
index 000000000000..4625ba91f609
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_dio.h
@@ -0,0 +1,69 @@
1/**
2 * @file me4600_dio.h
3 *
4 * @brief ME-4000 digital input/output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME4600_DIO_H_
28#define _ME4600_DIO_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me4600_dio_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
44 unsigned int dio_idx; /**< The index of the digital i/o on the device. */
45
46 /* Registers */
47 unsigned long port_reg; /**< Register holding the port status. */
48 unsigned long ctrl_reg; /**< Register to configure the port direction. */
49#ifdef MEDEBUG_DEBUG_REG
50 unsigned long reg_base;
51#endif
52} me4600_dio_subdevice_t;
53
54/**
55 * @brief The constructor to generate a ME-4000 digital input/ouput subdevice instance.
56 *
57 * @param reg_base The register base address of the device as returned by the PCI BIOS.
58 * @param dio_idx The index of the digital i/o port on the device.
59 * @param ctrl_reg_lock Spin lock protecting the control register.
60 *
61 * @return Pointer to new instance on success.\n
62 * NULL on error.
63 */
64me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base,
65 unsigned int dio_idx,
66 spinlock_t * ctrl_reg_lock);
67
68#endif
69#endif
diff --git a/drivers/staging/meilhaus/me4600_dio_reg.h b/drivers/staging/meilhaus/me4600_dio_reg.h
new file mode 100644
index 000000000000..7a4016a80fd2
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_dio_reg.h
@@ -0,0 +1,63 @@
1/**
2 * @file me4600_dio_reg.h
3 *
4 * @brief ME-4000 digital input/output subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME4600_DIO_REG_H_
28#define _ME4600_DIO_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME4600_DIO_PORT_0_REG 0xA0 /**< Port 0 register. */
33#define ME4600_DIO_PORT_1_REG 0xA4 /**< Port 1 register. */
34#define ME4600_DIO_PORT_2_REG 0xA8 /**< Port 2 register. */
35#define ME4600_DIO_PORT_3_REG 0xAC /**< Port 3 register. */
36
37#define ME4600_DIO_DIR_REG 0xB0 /**< Direction register. */
38#define ME4600_DIO_PORT_REG ME4600_DIO_PORT_0_REG /**< Base for port's register. */
39
40#define ME4600_DIO_CTRL_REG 0xB8 /**< Control register. */
41/** Port A - DO */
42#define ME4600_DIO_CTRL_BIT_MODE_0 0x0001
43#define ME4600_DIO_CTRL_BIT_MODE_1 0x0002
44/** Port B - DI */
45#define ME4600_DIO_CTRL_BIT_MODE_2 0x0004
46#define ME4600_DIO_CTRL_BIT_MODE_3 0x0008
47/** Port C - DIO */
48#define ME4600_DIO_CTRL_BIT_MODE_4 0x0010
49#define ME4600_DIO_CTRL_BIT_MODE_5 0x0020
50/** Port D - DIO */
51#define ME4600_DIO_CTRL_BIT_MODE_6 0x0040
52#define ME4600_DIO_CTRL_BIT_MODE_7 0x0080
53
54#define ME4600_DIO_CTRL_BIT_FUNCTION_0 0x0100
55#define ME4600_DIO_CTRL_BIT_FUNCTION_1 0x0200
56
57#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 0x0400
58#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_1 0x0800
59#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_2 0x1000
60#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_3 0x2000
61
62#endif
63#endif
diff --git a/drivers/staging/meilhaus/me4600_do.c b/drivers/staging/meilhaus/me4600_do.c
new file mode 100644
index 000000000000..ee591bc1185e
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_do.c
@@ -0,0 +1,433 @@
1/**
2 * @file me4600_do.c
3 *
4 * @brief ME-4000 digital output 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45
46#include "medebug.h"
47#include "me4600_dio_reg.h"
48#include "me4600_do.h"
49
50/*
51 * Defines
52 */
53
54/*
55 * Functions
56 */
57
58static int me4600_do_io_reset_subdevice(struct me_subdevice *subdevice,
59 struct file *filep, int flags)
60{
61 me4600_do_subdevice_t *instance;
62 uint32_t mode;
63
64 PDEBUG("executed.\n");
65
66 instance = (me4600_do_subdevice_t *) subdevice;
67
68 if (flags) {
69 PERROR("Invalid flag specified.\n");
70 return ME_ERRNO_INVALID_FLAGS;
71 }
72
73 ME_SUBDEVICE_ENTER;
74
75 /* Set port to output mode */
76 spin_lock(&instance->subdevice_lock);
77 spin_lock(instance->ctrl_reg_lock);
78 mode = inl(instance->ctrl_reg);
79 mode &= ~ME4600_DIO_CTRL_BIT_MODE_1; //0xFFFD
80 mode |= ME4600_DIO_CTRL_BIT_MODE_0; //0x1
81 outl(mode, instance->ctrl_reg);
82 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
83 instance->ctrl_reg - instance->reg_base, mode);
84 spin_unlock(instance->ctrl_reg_lock);
85
86 outl(0, instance->port_reg);
87 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
88 instance->port_reg - instance->reg_base, 0);
89 spin_unlock(&instance->subdevice_lock);
90
91 ME_SUBDEVICE_EXIT;
92
93 return ME_ERRNO_SUCCESS;
94}
95
96static int me4600_do_io_single_config(me_subdevice_t * subdevice,
97 struct file *filep,
98 int channel,
99 int single_config,
100 int ref,
101 int trig_chan,
102 int trig_type, int trig_edge, int flags)
103{
104 me4600_do_subdevice_t *instance;
105 int err = ME_ERRNO_SUCCESS;
106 uint32_t mode;
107 int size =
108 flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
109 | ME_IO_SINGLE_CONFIG_DIO_WORD |
110 ME_IO_SINGLE_CONFIG_DIO_DWORD);
111
112 PDEBUG("executed.\n");
113
114 instance = (me4600_do_subdevice_t *) subdevice;
115
116 ME_SUBDEVICE_ENTER;
117
118 spin_lock(&instance->subdevice_lock);
119 spin_lock(instance->ctrl_reg_lock);
120 mode = inl(instance->ctrl_reg);
121
122 switch (size) {
123 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
124 case ME_IO_SINGLE_CONFIG_DIO_BYTE:
125 if (channel == 0) {
126 if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
127 mode &= ~(ME4600_DIO_CTRL_BIT_MODE_0 |
128 ME4600_DIO_CTRL_BIT_MODE_1);
129 mode |= (ME4600_DIO_CTRL_BIT_MODE_0);
130 } else if (single_config == ME_SINGLE_CONFIG_DIO_MUX32M) {
131 mode &= ~(ME4600_DIO_CTRL_BIT_MODE_0 |
132 ME4600_DIO_CTRL_BIT_MODE_1 |
133 ME4600_DIO_CTRL_BIT_FUNCTION_0 |
134 ME4600_DIO_CTRL_BIT_FUNCTION_1 |
135 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
136
137 if (ref == ME_REF_DIO_FIFO_LOW) {
138 mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
139 ME4600_DIO_CTRL_BIT_MODE_1 |
140 ME4600_DIO_CTRL_BIT_FUNCTION_1);
141 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
142 mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
143 ME4600_DIO_CTRL_BIT_MODE_1 |
144 ME4600_DIO_CTRL_BIT_FUNCTION_1
145 |
146 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
147 } else {
148 PERROR
149 ("Invalid port reference specified.\n");
150 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
151 }
152 } else if (single_config ==
153 ME_SINGLE_CONFIG_DIO_DEMUX32) {
154 mode &=
155 ~(ME4600_DIO_CTRL_BIT_MODE_0 |
156 ME4600_DIO_CTRL_BIT_MODE_1 |
157 ME4600_DIO_CTRL_BIT_FUNCTION_0 |
158 ME4600_DIO_CTRL_BIT_FUNCTION_1 |
159 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
160
161 if (ref == ME_REF_DIO_FIFO_LOW) {
162 mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
163 ME4600_DIO_CTRL_BIT_MODE_1 |
164 ME4600_DIO_CTRL_BIT_FUNCTION_0);
165 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
166 mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
167 ME4600_DIO_CTRL_BIT_MODE_1 |
168 ME4600_DIO_CTRL_BIT_FUNCTION_0
169 |
170 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
171 } else {
172 PERROR
173 ("Invalid port reference specified.\n");
174 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
175 }
176 } else if (single_config ==
177 ME_SINGLE_CONFIG_DIO_BIT_PATTERN) {
178 mode &=
179 ~(ME4600_DIO_CTRL_BIT_MODE_0 |
180 ME4600_DIO_CTRL_BIT_MODE_1 |
181 ME4600_DIO_CTRL_BIT_FUNCTION_0 |
182 ME4600_DIO_CTRL_BIT_FUNCTION_1 |
183 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
184
185 if (ref == ME_REF_DIO_FIFO_LOW) {
186 mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
187 ME4600_DIO_CTRL_BIT_MODE_1);
188 } else if (ref == ME_REF_DIO_FIFO_HIGH) {
189 mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
190 ME4600_DIO_CTRL_BIT_MODE_1 |
191 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
192 } else {
193 PERROR
194 ("Invalid port reference specified.\n");
195 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
196 }
197 } else {
198 PERROR("Invalid port direction specified.\n");
199 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
200 }
201 } else {
202 PERROR("Invalid channel number.\n");
203 err = ME_ERRNO_INVALID_CHANNEL;
204 }
205
206 break;
207
208 default:
209 PERROR("Invalid flags specified.\n");
210 err = ME_ERRNO_INVALID_FLAGS;
211 }
212
213 if (!err) {
214 outl(mode, instance->ctrl_reg);
215 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
216 instance->reg_base,
217 instance->ctrl_reg - instance->reg_base, mode);
218 }
219 spin_unlock(instance->ctrl_reg_lock);
220 spin_unlock(&instance->subdevice_lock);
221
222 ME_SUBDEVICE_EXIT;
223
224 return err;
225}
226
227static int me4600_do_io_single_read(me_subdevice_t * subdevice,
228 struct file *filep,
229 int channel,
230 int *value, int time_out, int flags)
231{
232 me4600_do_subdevice_t *instance;
233 int err = ME_ERRNO_SUCCESS;
234 uint32_t mode;
235
236 PDEBUG("executed.\n");
237
238 instance = (me4600_do_subdevice_t *) subdevice;
239
240 ME_SUBDEVICE_ENTER;
241
242 spin_lock(&instance->subdevice_lock);
243 spin_lock(instance->ctrl_reg_lock);
244 mode =
245 inl(instance->
246 ctrl_reg) & (ME4600_DIO_CTRL_BIT_MODE_0 |
247 ME4600_DIO_CTRL_BIT_MODE_1);
248
249 if (mode == ME4600_DIO_CTRL_BIT_MODE_0) {
250 switch (flags) {
251 case ME_IO_SINGLE_TYPE_DIO_BIT:
252 if ((channel >= 0) && (channel < 8)) {
253 *value =
254 inl(instance->port_reg) & (0x1 << channel);
255 } else {
256 PERROR("Invalid bit number specified.\n");
257 err = ME_ERRNO_INVALID_CHANNEL;
258 }
259 break;
260
261 case ME_IO_SINGLE_NO_FLAGS:
262 case ME_IO_SINGLE_TYPE_DIO_BYTE:
263 if (channel == 0) {
264 *value = inl(instance->port_reg) & 0xFF;
265 } else {
266 PERROR("Invalid byte number specified.\n");
267 err = ME_ERRNO_INVALID_CHANNEL;
268 }
269 break;
270
271 default:
272 PERROR("Invalid flags specified.\n");
273 err = ME_ERRNO_INVALID_FLAGS;
274 }
275 } else {
276 PERROR("Port not in output mode.\n");
277 err = ME_ERRNO_PREVIOUS_CONFIG;
278 }
279 spin_unlock(instance->ctrl_reg_lock);
280 spin_unlock(&instance->subdevice_lock);
281
282 ME_SUBDEVICE_EXIT;
283
284 return err;
285}
286
287static int me4600_do_io_single_write(me_subdevice_t * subdevice,
288 struct file *filep,
289 int channel,
290 int value, int time_out, int flags)
291{
292 me4600_do_subdevice_t *instance;
293 int err = ME_ERRNO_SUCCESS;
294 uint32_t byte;
295 uint32_t mode;
296
297 PDEBUG("executed.\n");
298
299 instance = (me4600_do_subdevice_t *) subdevice;
300
301 ME_SUBDEVICE_ENTER;
302
303 spin_lock(&instance->subdevice_lock);
304 spin_lock(instance->ctrl_reg_lock);
305 mode =
306 inl(instance->
307 ctrl_reg) & (ME4600_DIO_CTRL_BIT_MODE_0 |
308 ME4600_DIO_CTRL_BIT_MODE_1);
309
310 if (mode == ME4600_DIO_CTRL_BIT_MODE_0) {
311 switch (flags) {
312
313 case ME_IO_SINGLE_TYPE_DIO_BIT:
314 if ((channel >= 0) && (channel < 8)) {
315 byte = inl(instance->port_reg) & 0xFF;
316
317 if (value)
318 byte |= 0x1 << channel;
319 else
320 byte &= ~(0x1 << channel);
321
322 outl(byte, instance->port_reg);
323 } else {
324 PERROR("Invalid bit number specified.\n");
325 err = ME_ERRNO_INVALID_CHANNEL;
326 }
327 break;
328
329 case ME_IO_SINGLE_NO_FLAGS:
330 case ME_IO_SINGLE_TYPE_DIO_BYTE:
331 if (channel == 0) {
332 outl(value, instance->port_reg);
333 } else {
334 PERROR("Invalid byte number specified.\n");
335 err = ME_ERRNO_INVALID_CHANNEL;
336 }
337 break;
338
339 default:
340 PERROR("Invalid flags specified.\n");
341 err = ME_ERRNO_INVALID_FLAGS;
342 }
343 } else {
344 PERROR("Port not in output mode.\n");
345 err = ME_ERRNO_PREVIOUS_CONFIG;
346 }
347 spin_unlock(instance->ctrl_reg_lock);
348 spin_unlock(&instance->subdevice_lock);
349
350 ME_SUBDEVICE_EXIT;
351
352 return err;
353}
354
355static int me4600_do_query_number_channels(me_subdevice_t * subdevice,
356 int *number)
357{
358 PDEBUG("executed.\n");
359 *number = 8;
360 return ME_ERRNO_SUCCESS;
361}
362
363static int me4600_do_query_subdevice_type(me_subdevice_t * subdevice,
364 int *type, int *subtype)
365{
366 PDEBUG("executed.\n");
367 *type = ME_TYPE_DO;
368 *subtype = ME_SUBTYPE_SINGLE;
369 return ME_ERRNO_SUCCESS;
370}
371
372static int me4600_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
373{
374 PDEBUG("executed.\n");
375 *caps = 0;
376 return ME_ERRNO_SUCCESS;
377}
378
379me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base,
380 spinlock_t * ctrl_reg_lock)
381{
382 me4600_do_subdevice_t *subdevice;
383 int err;
384
385 PDEBUG("executed.\n");
386
387 /* Allocate memory for subdevice instance */
388 subdevice = kmalloc(sizeof(me4600_do_subdevice_t), GFP_KERNEL);
389
390 if (!subdevice) {
391 PERROR("Cannot get memory for subdevice instance.\n");
392 return NULL;
393 }
394
395 memset(subdevice, 0, sizeof(me4600_do_subdevice_t));
396
397 /* Initialize subdevice base class */
398 err = me_subdevice_init(&subdevice->base);
399
400 if (err) {
401 PERROR("Cannot initialize subdevice base class instance.\n");
402 kfree(subdevice);
403 return NULL;
404 }
405 // Initialize spin locks.
406 spin_lock_init(&subdevice->subdevice_lock);
407
408 subdevice->ctrl_reg_lock = ctrl_reg_lock;
409
410 /* Save the subdevice index */
411 subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
412 subdevice->port_reg = reg_base + ME4600_DIO_PORT_0_REG;
413#ifdef MEDEBUG_DEBUG_REG
414 subdevice->reg_base = reg_base;
415#endif
416
417 /* Overload base class methods. */
418 subdevice->base.me_subdevice_io_reset_subdevice =
419 me4600_do_io_reset_subdevice;
420 subdevice->base.me_subdevice_io_single_config =
421 me4600_do_io_single_config;
422 subdevice->base.me_subdevice_io_single_read = me4600_do_io_single_read;
423 subdevice->base.me_subdevice_io_single_write =
424 me4600_do_io_single_write;
425 subdevice->base.me_subdevice_query_number_channels =
426 me4600_do_query_number_channels;
427 subdevice->base.me_subdevice_query_subdevice_type =
428 me4600_do_query_subdevice_type;
429 subdevice->base.me_subdevice_query_subdevice_caps =
430 me4600_do_query_subdevice_caps;
431
432 return subdevice;
433}
diff --git a/drivers/staging/meilhaus/me4600_do.h b/drivers/staging/meilhaus/me4600_do.h
new file mode 100644
index 000000000000..e8385648e925
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_do.h
@@ -0,0 +1,65 @@
1/**
2 * @file me4600_do.h
3 *
4 * @brief ME-4000 digital output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME4600_DO_H_
28#define _ME4600_DO_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me4600_do_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
44
45 unsigned long port_reg; /**< Register holding the port status. */
46 unsigned long ctrl_reg; /**< Register to configure the port direction. */
47#ifdef MEDEBUG_DEBUG_REG
48 unsigned long reg_base;
49#endif
50} me4600_do_subdevice_t;
51
52/**
53 * @brief The constructor to generate a ME-4000 digital output subdevice instance.
54 *
55 * @param reg_base The register base address of the device as returned by the PCI BIOS.
56 * @param ctrl_reg_lock Spin lock protecting the control register.
57 *
58 * @return Pointer to new instance on success.\n
59 * NULL on error.
60 */
61me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base,
62 spinlock_t * ctrl_reg_lock);
63
64#endif
65#endif
diff --git a/drivers/staging/meilhaus/me4600_ext_irq.c b/drivers/staging/meilhaus/me4600_ext_irq.c
new file mode 100644
index 000000000000..8a10dceae32a
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_ext_irq.c
@@ -0,0 +1,467 @@
1/**
2 * @file me4600_ext_irq.c
3 *
4 * @brief ME-4000 external interrupt 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 <linux/interrupt.h>
40#include <asm/io.h>
41#include <linux/types.h>
42#include <linux/version.h>
43
44#include "medefines.h"
45#include "meinternal.h"
46#include "meerror.h"
47
48#include "medebug.h"
49#include "meids.h"
50#include "me4600_reg.h"
51#include "me4600_ai_reg.h"
52#include "me4600_ext_irq_reg.h"
53#include "me4600_ext_irq.h"
54
55/*
56 * Defines
57 */
58
59/*
60 * Functions
61 */
62
63static int me4600_ext_irq_io_irq_start(me_subdevice_t * subdevice,
64 struct file *filep,
65 int channel,
66 int irq_source,
67 int irq_edge, int irq_arg, int flags)
68{
69 me4600_ext_irq_subdevice_t *instance;
70 int err = ME_ERRNO_SUCCESS;
71 unsigned long cpu_flags;
72 uint32_t tmp;
73
74 PDEBUG("executed.\n");
75
76 instance = (me4600_ext_irq_subdevice_t *) subdevice;
77
78 if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
79 PERROR("Invalid flag specified.\n");
80 return ME_ERRNO_INVALID_FLAGS;
81 }
82
83 if ((irq_edge != ME_IRQ_EDGE_RISING)
84 && (irq_edge != ME_IRQ_EDGE_FALLING)
85 && (irq_edge != ME_IRQ_EDGE_ANY)
86 ) {
87 PERROR("Invalid irq edge specified.\n");
88 return ME_ERRNO_INVALID_IRQ_EDGE;
89 }
90
91 if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
92 PERROR("Invalid irq source specified.\n");
93 return ME_ERRNO_INVALID_IRQ_SOURCE;
94 }
95
96 if (channel) {
97 PERROR("Invalid channel specified.\n");
98 return ME_ERRNO_INVALID_CHANNEL;
99 }
100
101 ME_SUBDEVICE_ENTER;
102
103 spin_lock(&instance->subdevice_lock);
104 tmp = 0x0; //inl(instance->ext_irq_config_reg);
105
106 if (irq_edge == ME_IRQ_EDGE_RISING) {
107 //tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK;
108 //tmp |= ME4600_EXT_IRQ_CONFIG_MASK_RISING;
109 } else if (irq_edge == ME_IRQ_EDGE_FALLING) {
110 //tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK;
111 //tmp |= ME4600_EXT_IRQ_CONFIG_MASK_FALLING;
112 tmp = ME4600_EXT_IRQ_CONFIG_MASK_FALLING;
113 } else if (irq_edge == ME_IRQ_EDGE_ANY) {
114 //tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK;
115 //tmp |= ME4600_EXT_IRQ_CONFIG_MASK_ANY;
116 tmp = ME4600_EXT_IRQ_CONFIG_MASK_ANY;
117 }
118
119 outl(tmp, instance->ext_irq_config_reg);
120 PDEBUG_REG("ext_irq_config_reg outl(0x%lX+0x%lX)=0x%x\n",
121 instance->reg_base,
122 instance->ext_irq_config_reg - instance->reg_base, tmp);
123
124 spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
125 tmp = inl(instance->ctrl_reg);
126 tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
127 tmp |= ME4600_AI_CTRL_BIT_EX_IRQ;
128 outl(tmp, instance->ctrl_reg);
129 spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
130 instance->rised = 0;
131 spin_unlock(&instance->subdevice_lock);
132
133 ME_SUBDEVICE_EXIT;
134
135 return err;
136}
137
138static int me4600_ext_irq_io_irq_wait(me_subdevice_t * subdevice,
139 struct file *filep,
140 int channel,
141 int *irq_count,
142 int *value, int time_out, int flags)
143{
144 me4600_ext_irq_subdevice_t *instance;
145 int err = ME_ERRNO_SUCCESS;
146 long t = 0;
147 unsigned long cpu_flags;
148
149 PDEBUG("executed.\n");
150
151 instance = (me4600_ext_irq_subdevice_t *) subdevice;
152
153 if (flags) {
154 PERROR("Invalid flag specified.\n");
155 return ME_ERRNO_INVALID_FLAGS;
156 }
157
158 if (channel) {
159 PERROR("Invalid channel specified.\n");
160 return ME_ERRNO_INVALID_CHANNEL;
161 }
162
163 if (time_out < 0) {
164 PERROR("Invalid time_out specified.\n");
165 return ME_ERRNO_INVALID_TIMEOUT;
166 }
167
168 if (time_out) {
169 t = (time_out * HZ) / 1000;
170
171 if (t == 0)
172 t = 1;
173 }
174
175 ME_SUBDEVICE_ENTER;
176
177 if (instance->rised <= 0) {
178 instance->rised = 0;
179 if (time_out) {
180 t = wait_event_interruptible_timeout(instance->
181 wait_queue,
182 (instance->rised !=
183 0), t);
184
185 if (t == 0) {
186 PERROR
187 ("Wait on external interrupt timed out.\n");
188 err = ME_ERRNO_TIMEOUT;
189 }
190 } else {
191 wait_event_interruptible(instance->wait_queue,
192 (instance->rised != 0));
193 }
194
195 if (instance->rised < 0) {
196 PERROR("Wait on interrupt aborted by user.\n");
197 err = ME_ERRNO_CANCELLED;
198 }
199 }
200
201 if (signal_pending(current)) {
202 PERROR("Wait on external interrupt aborted by signal.\n");
203 err = ME_ERRNO_SIGNAL;
204 }
205
206 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
207 instance->rised = 0;
208 *irq_count = instance->count;
209 *value = instance->value;
210 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
211
212 ME_SUBDEVICE_EXIT;
213
214 return err;
215}
216
217static int me4600_ext_irq_io_irq_stop(me_subdevice_t * subdevice,
218 struct file *filep,
219 int channel, int flags)
220{
221 me4600_ext_irq_subdevice_t *instance;
222 int err = ME_ERRNO_SUCCESS;
223 unsigned long cpu_flags;
224 uint32_t tmp;
225
226 PDEBUG("executed.\n");
227
228 instance = (me4600_ext_irq_subdevice_t *) subdevice;
229
230 if (flags) {
231 PERROR("Invalid flag specified.\n");
232 return ME_ERRNO_INVALID_FLAGS;
233 }
234
235 if (channel) {
236 PERROR("Invalid channel specified.\n");
237 return ME_ERRNO_INVALID_CHANNEL;
238 }
239
240 ME_SUBDEVICE_ENTER;
241
242 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
243 spin_lock(instance->ctrl_reg_lock);
244 tmp = inl(instance->ctrl_reg);
245 tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
246 outl(tmp, instance->ctrl_reg);
247 PDEBUG_REG("ctrl_regv outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
248 instance->ctrl_reg - instance->reg_base, tmp);
249 spin_unlock(instance->ctrl_reg_lock);
250 instance->rised = -1;
251 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
252 wake_up_interruptible_all(&instance->wait_queue);
253
254 ME_SUBDEVICE_EXIT;
255
256 return err;
257}
258
259static int me4600_ext_irq_io_reset_subdevice(me_subdevice_t * subdevice,
260 struct file *filep, int flags)
261{
262 me4600_ext_irq_subdevice_t *instance;
263 unsigned long cpu_flags;
264 uint32_t tmp;
265
266 PDEBUG("executed.\n");
267
268 instance = (me4600_ext_irq_subdevice_t *) subdevice;
269
270 if (flags) {
271 PERROR("Invalid flag specified.\n");
272 return ME_ERRNO_INVALID_FLAGS;
273 }
274
275 ME_SUBDEVICE_ENTER;
276
277 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
278 spin_lock(instance->ctrl_reg_lock);
279 tmp = inl(instance->ctrl_reg);
280 tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
281 outl(tmp, instance->ctrl_reg);
282 PDEBUG_REG("ctrl_regv outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
283 instance->ctrl_reg - instance->reg_base, tmp);
284 spin_unlock(instance->ctrl_reg_lock);
285 instance->rised = -1;
286 instance->count = 0;
287 outl(ME4600_EXT_IRQ_CONFIG_MASK_ANY, instance->ext_irq_config_reg);
288 PDEBUG_REG("ext_irq_config_reg outl(0x%lX+0x%lX)=0x%x\n",
289 instance->reg_base,
290 instance->ext_irq_config_reg - instance->reg_base,
291 ME4600_EXT_IRQ_CONFIG_MASK_ANY);
292 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
293 wake_up_interruptible_all(&instance->wait_queue);
294
295 ME_SUBDEVICE_EXIT;
296
297 return ME_ERRNO_SUCCESS;
298}
299
300static void me4600_ext_irq_destructor(struct me_subdevice *subdevice)
301{
302 me4600_ext_irq_subdevice_t *instance;
303
304 PDEBUG("executed.\n");
305 instance = (me4600_ext_irq_subdevice_t *) subdevice;
306 me_subdevice_deinit(&instance->base);
307 free_irq(instance->irq, instance);
308 kfree(instance);
309}
310
311static int me4600_ext_irq_query_number_channels(me_subdevice_t * subdevice,
312 int *number)
313{
314 PDEBUG("executed.\n");
315 *number = 1;
316 return ME_ERRNO_SUCCESS;
317}
318
319static int me4600_ext_irq_query_subdevice_type(me_subdevice_t * subdevice,
320 int *type, int *subtype)
321{
322 PDEBUG("executed.\n");
323 *type = ME_TYPE_EXT_IRQ;
324 *subtype = ME_SUBTYPE_SINGLE;
325 return ME_ERRNO_SUCCESS;
326}
327
328static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t * subdevice,
329 int *caps)
330{
331 PDEBUG("executed.\n");
332 *caps =
333 ME_CAPS_EXT_IRQ_EDGE_RISING | ME_CAPS_EXT_IRQ_EDGE_FALLING |
334 ME_CAPS_EXT_IRQ_EDGE_ANY;
335 return ME_ERRNO_SUCCESS;
336}
337
338#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
339static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id)
340#else
341static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id,
342 struct pt_regs *regs)
343#endif
344{
345 me4600_ext_irq_subdevice_t *instance;
346 uint32_t ctrl;
347 uint32_t irq_status;
348
349 instance = (me4600_ext_irq_subdevice_t *) dev_id;
350
351 if (irq != instance->irq) {
352 PERROR("Incorrect interrupt num: %d.\n", irq);
353 return IRQ_NONE;
354 }
355
356 irq_status = inl(instance->irq_status_reg);
357 if (!(irq_status & ME4600_IRQ_STATUS_BIT_EX)) {
358 PINFO("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n",
359 jiffies, __FUNCTION__, irq_status);
360 return IRQ_NONE;
361 }
362
363 PDEBUG("executed.\n");
364
365 spin_lock(&instance->subdevice_lock);
366 instance->rised = 1;
367 instance->value = inl(instance->ext_irq_value_reg);
368 instance->count++;
369
370 spin_lock(instance->ctrl_reg_lock);
371 ctrl = inl(instance->ctrl_reg);
372 ctrl |= ME4600_AI_CTRL_BIT_EX_IRQ_RESET;
373 outl(ctrl, instance->ctrl_reg);
374 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
375 instance->ctrl_reg - instance->reg_base, ctrl);
376 ctrl &= ~ME4600_AI_CTRL_BIT_EX_IRQ_RESET;
377 outl(ctrl, instance->ctrl_reg);
378 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
379 instance->ctrl_reg - instance->reg_base, ctrl);
380 spin_unlock(instance->ctrl_reg_lock);
381
382 spin_unlock(&instance->subdevice_lock);
383 wake_up_interruptible_all(&instance->wait_queue);
384
385 return IRQ_HANDLED;
386}
387
388me4600_ext_irq_subdevice_t *me4600_ext_irq_constructor(uint32_t reg_base,
389 int irq,
390 spinlock_t *
391 ctrl_reg_lock)
392{
393 me4600_ext_irq_subdevice_t *subdevice;
394 int err;
395
396 PDEBUG("executed.\n");
397
398 /* Allocate memory for subdevice instance */
399 subdevice = kmalloc(sizeof(me4600_ext_irq_subdevice_t), GFP_KERNEL);
400
401 if (!subdevice) {
402 PERROR("Cannot get memory for subdevice instance.\n");
403 return NULL;
404 }
405
406 memset(subdevice, 0, sizeof(me4600_ext_irq_subdevice_t));
407
408 /* Initialize subdevice base class */
409 err = me_subdevice_init(&subdevice->base);
410
411 if (err) {
412 PERROR("Cannot initialize subdevice base class instance.\n");
413 kfree(subdevice);
414 return NULL;
415 }
416 // Initialize spin locks.
417 spin_lock_init(&subdevice->subdevice_lock);
418
419 subdevice->ctrl_reg_lock = ctrl_reg_lock;
420
421 /* Initialize wait queue */
422 init_waitqueue_head(&subdevice->wait_queue);
423
424 /* Register interrupt */
425 subdevice->irq = irq;
426
427 if (request_irq(subdevice->irq, me4600_ext_irq_isr,
428#ifdef IRQF_DISABLED
429 IRQF_DISABLED | IRQF_SHARED,
430#else
431 SA_INTERRUPT | SA_SHIRQ,
432#endif
433 ME4600_NAME, subdevice)) {
434 PERROR("Cannot register interrupt.\n");
435 kfree(subdevice);
436 return NULL;
437 }
438 PINFO("Registered irq=%d.\n", subdevice->irq);
439
440 /* Initialize registers */
441 subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
442 subdevice->ctrl_reg = reg_base + ME4600_AI_CTRL_REG;
443 subdevice->ext_irq_config_reg = reg_base + ME4600_EXT_IRQ_CONFIG_REG;
444 subdevice->ext_irq_value_reg = reg_base + ME4600_EXT_IRQ_VALUE_REG;
445#ifdef MEDEBUG_DEBUG_REG
446 subdevice->reg_base = reg_base;
447#endif
448
449 /* Override base class methods. */
450 subdevice->base.me_subdevice_destructor = me4600_ext_irq_destructor;
451 subdevice->base.me_subdevice_io_reset_subdevice =
452 me4600_ext_irq_io_reset_subdevice;
453 subdevice->base.me_subdevice_io_irq_start = me4600_ext_irq_io_irq_start;
454 subdevice->base.me_subdevice_io_irq_wait = me4600_ext_irq_io_irq_wait;
455 subdevice->base.me_subdevice_io_irq_stop = me4600_ext_irq_io_irq_stop;
456 subdevice->base.me_subdevice_query_number_channels =
457 me4600_ext_irq_query_number_channels;
458 subdevice->base.me_subdevice_query_subdevice_type =
459 me4600_ext_irq_query_subdevice_type;
460 subdevice->base.me_subdevice_query_subdevice_caps =
461 me4600_ext_irq_query_subdevice_caps;
462
463 subdevice->rised = 0;
464 subdevice->count = 0;
465
466 return subdevice;
467}
diff --git a/drivers/staging/meilhaus/me4600_ext_irq.h b/drivers/staging/meilhaus/me4600_ext_irq.h
new file mode 100644
index 000000000000..3c7b27f9e5dc
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_ext_irq.h
@@ -0,0 +1,78 @@
1/**
2 * @file me4600_ext_irq.h
3 *
4 * @brief Meilhaus ME-4000 external interrupt subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME4600_EXT_IRQ_H_
28#define _ME4600_EXT_IRQ_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The subdevice class.
36 */
37typedef struct me4600_ext_irq_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
44
45 wait_queue_head_t wait_queue;
46
47 int irq;
48
49 int rised;
50 int value;
51 int count;
52
53 unsigned long ctrl_reg;
54 unsigned long irq_status_reg;
55 unsigned long ext_irq_config_reg;
56 unsigned long ext_irq_value_reg;
57#ifdef MEDEBUG_DEBUG_REG
58 unsigned long reg_base;
59#endif
60} me4600_ext_irq_subdevice_t;
61
62/**
63 * @brief The constructor to generate a external interrupt subdevice instance.
64 *
65 * @param reg_base The register base address of the device as returned by the PCI BIOS.
66 * @param irq The interrupt number assigned by the PCI BIOS.
67 * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
68 *
69 * @return Pointer to new instance on success.\n
70 * NULL on error.
71 */
72me4600_ext_irq_subdevice_t *me4600_ext_irq_constructor(uint32_t reg_base,
73 int irq,
74 spinlock_t *
75 ctrl_reg_lock);
76
77#endif
78#endif
diff --git a/drivers/staging/meilhaus/me4600_ext_irq_reg.h b/drivers/staging/meilhaus/me4600_ext_irq_reg.h
new file mode 100644
index 000000000000..898e1e74d9e7
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_ext_irq_reg.h
@@ -0,0 +1,41 @@
1/**
2 * @file me4600_ext_irq_reg.h
3 *
4 * @brief ME-4000 external interrupt subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME4600_EXT_IRQ_REG_H_
28#define _ME4600_EXT_IRQ_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME4600_EXT_IRQ_CONFIG_REG 0xCC // R/_
33#define ME4600_EXT_IRQ_VALUE_REG 0xD0 // R/_
34
35#define ME4600_EXT_IRQ_CONFIG_MASK_RISING 0x0
36#define ME4600_EXT_IRQ_CONFIG_MASK_FALLING 0x1
37#define ME4600_EXT_IRQ_CONFIG_MASK_ANY 0x3
38#define ME4600_EXT_IRQ_CONFIG_MASK 0x3
39
40#endif
41#endif
diff --git a/drivers/staging/meilhaus/me4600_reg.h b/drivers/staging/meilhaus/me4600_reg.h
new file mode 100644
index 000000000000..ae152bbc6a3d
--- /dev/null
+++ b/drivers/staging/meilhaus/me4600_reg.h
@@ -0,0 +1,46 @@
1/**
2 * @file me4600_reg.h
3 *
4 * @brief ME-4000 register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME4600_REG_H_
28#define _ME4600_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME4600_IRQ_STATUS_REG 0x9C // R/_
33
34#define ME4600_IRQ_STATUS_BIT_EX 0x01
35#define ME4600_IRQ_STATUS_BIT_LE 0x02
36#define ME4600_IRQ_STATUS_BIT_AI_HF 0x04
37#define ME4600_IRQ_STATUS_BIT_AO_0_HF 0x08
38#define ME4600_IRQ_STATUS_BIT_AO_1_HF 0x10
39#define ME4600_IRQ_STATUS_BIT_AO_2_HF 0x20
40#define ME4600_IRQ_STATUS_BIT_AO_3_HF 0x40
41#define ME4600_IRQ_STATUS_BIT_SC 0x80
42
43#define ME4600_IRQ_STATUS_BIT_AO_HF ME4600_IRQ_STATUS_BIT_AO_0_HF
44
45#endif
46#endif
diff --git a/drivers/staging/meilhaus/me6000_ao.c b/drivers/staging/meilhaus/me6000_ao.c
new file mode 100644
index 000000000000..3f5ff6d1b991
--- /dev/null
+++ b/drivers/staging/meilhaus/me6000_ao.c
@@ -0,0 +1,3739 @@
1/**
2 * @file me6000_ao.c
3 *
4 * @brief ME-6000 analog output 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 */
34#include <linux/version.h>
35#include <linux/module.h>
36
37#include <linux/slab.h>
38#include <linux/spinlock.h>
39#include <asm/io.h>
40#include <asm/uaccess.h>
41#include <linux/types.h>
42#include <linux/interrupt.h>
43#include <linux/delay.h>
44
45#include <linux/workqueue.h>
46
47#include "medefines.h"
48#include "meinternal.h"
49#include "meerror.h"
50
51#include "medebug.h"
52#include "meids.h"
53#include "me6000_reg.h"
54#include "me6000_ao_reg.h"
55#include "me6000_ao.h"
56
57/* Defines
58 */
59
60static int me6000_ao_query_range_by_min_max(me_subdevice_t * subdevice,
61 int unit,
62 int *min,
63 int *max, int *maxdata, int *range);
64
65static int me6000_ao_query_number_ranges(me_subdevice_t * subdevice,
66 int unit, int *count);
67
68static int me6000_ao_query_range_info(me_subdevice_t * subdevice,
69 int range,
70 int *unit,
71 int *min, int *max, int *maxdata);
72
73static int me6000_ao_query_timer(me_subdevice_t * subdevice,
74 int timer,
75 int *base_frequency,
76 long long *min_ticks, long long *max_ticks);
77
78static int me6000_ao_query_number_channels(me_subdevice_t * subdevice,
79 int *number);
80
81static int me6000_ao_query_subdevice_type(me_subdevice_t * subdevice,
82 int *type, int *subtype);
83
84static int me6000_ao_query_subdevice_caps(me_subdevice_t * subdevice,
85 int *caps);
86
87static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
88 int cap, int *args, int count);
89
90/** Remove subdevice. */
91static void me6000_ao_destructor(struct me_subdevice *subdevice);
92
93/** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'. */
94static int me6000_ao_io_reset_subdevice(me_subdevice_t * subdevice,
95 struct file *filep, int flags);
96
97/** Set output as single */
98static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
99 struct file *filep,
100 int channel,
101 int single_config,
102 int ref,
103 int trig_chan,
104 int trig_type, int trig_edge, int flags);
105
106/** Pass to user actual value of output. */
107static int me6000_ao_io_single_read(me_subdevice_t * subdevice,
108 struct file *filep,
109 int channel,
110 int *value, int time_out, int flags);
111
112/** Write to output requed value. */
113static int me6000_ao_io_single_write(me_subdevice_t * subdevice,
114 struct file *filep,
115 int channel,
116 int value, int time_out, int flags);
117
118/** Set output as streamed device. */
119static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
120 struct file *filep,
121 meIOStreamConfig_t * config_list,
122 int count,
123 meIOStreamTrigger_t * trigger,
124 int fifo_irq_threshold, int flags);
125
126/** Wait for / Check empty space in buffer. */
127static int me6000_ao_io_stream_new_values(me_subdevice_t * subdevice,
128 struct file *filep,
129 int time_out, int *count, int flags);
130
131/** Start streaming. */
132static int me6000_ao_io_stream_start(me_subdevice_t * subdevice,
133 struct file *filep,
134 int start_mode, int time_out, int flags);
135
136/** Check actual state. / Wait for end. */
137static int me6000_ao_io_stream_status(me_subdevice_t * subdevice,
138 struct file *filep,
139 int wait,
140 int *status, int *values, int flags);
141
142/** Stop streaming. */
143static int me6000_ao_io_stream_stop(me_subdevice_t * subdevice,
144 struct file *filep,
145 int stop_mode, int flags);
146
147/** Write datas to buffor. */
148static int me6000_ao_io_stream_write(me_subdevice_t * subdevice,
149 struct file *filep,
150 int write_mode,
151 int *values, int *count, int flags);
152
153/** Interrupt handler. Copy from buffer to FIFO. */
154#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
155static irqreturn_t me6000_ao_isr(int irq, void *dev_id);
156#else
157static irqreturn_t me6000_ao_isr(int irq, void *dev_id, struct pt_regs *regs);
158#endif
159
160/** Copy data from circular buffer to fifo (fast) in wraparound mode. */
161int inline ao_write_data_wraparound(me6000_ao_subdevice_t * instance, int count,
162 int start_pos);
163
164/** Copy data from circular buffer to fifo (fast).*/
165int inline ao_write_data(me6000_ao_subdevice_t * instance, int count,
166 int start_pos);
167
168/** Copy data from circular buffer to fifo (slow).*/
169int inline ao_write_data_pooling(me6000_ao_subdevice_t * instance, int count,
170 int start_pos);
171
172/** Copy data from user space to circular buffer. */
173int inline ao_get_data_from_user(me6000_ao_subdevice_t * instance, int count,
174 int *user_values);
175
176/** Stop presentation. Preserve FIFOs. */
177int inline ao_stop_immediately(me6000_ao_subdevice_t * instance);
178
179/** Function for checking timeout in non-blocking mode. */
180#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
181static void me6000_ao_work_control_task(void *subdevice);
182#else
183static void me6000_ao_work_control_task(struct work_struct *work);
184#endif
185
186/* Functions
187 */
188
189static int me6000_ao_io_reset_subdevice(me_subdevice_t * subdevice,
190 struct file *filep, int flags)
191{
192 me6000_ao_subdevice_t *instance;
193 int err = ME_ERRNO_SUCCESS;
194 uint32_t tmp;
195 uint32_t ctrl;
196
197 instance = (me6000_ao_subdevice_t *) subdevice;
198
199 PDEBUG("executed. idx=%d\n", instance->ao_idx);
200
201 if (flags) {
202 PERROR("Invalid flag specified.\n");
203 return ME_ERRNO_INVALID_FLAGS;
204 }
205
206 ME_SUBDEVICE_ENTER;
207
208 instance->status = ao_status_none;
209 instance->ao_control_task_flag = 0;
210 cancel_delayed_work(&instance->ao_control_task);
211 instance->timeout.delay = 0;
212 instance->timeout.start_time = jiffies;
213
214 //Stop state machine.
215 err = ao_stop_immediately(instance);
216
217 //Remove from synchronous start.
218 spin_lock(instance->preload_reg_lock);
219 tmp = inl(instance->preload_reg);
220 tmp &=
221 ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->
222 ao_idx);
223 outl(tmp, instance->preload_reg);
224 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
225 instance->preload_reg - instance->reg_base, tmp);
226 *instance->preload_flags &=
227 ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->
228 ao_idx);
229
230 //Reset triggering flag
231 *instance->triggering_flags &= ~(0x1 << instance->ao_idx);
232 spin_unlock(instance->preload_reg_lock);
233
234 if (instance->fifo) {
235 //Set single mode, dissable FIFO, dissable external trigger, block interrupt.
236 ctrl = ME6000_AO_MODE_SINGLE;
237
238 //Block ISM.
239 ctrl |=
240 (ME6000_AO_CTRL_BIT_STOP |
241 ME6000_AO_CTRL_BIT_IMMEDIATE_STOP);
242
243 outl(ctrl, instance->ctrl_reg);
244 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
245 instance->reg_base,
246 instance->ctrl_reg - instance->reg_base, ctrl);
247 //Set speed
248 outl(ME6000_AO_MIN_CHAN_TICKS - 1, instance->timer_reg);
249 //Reset interrupt latch
250 inl(instance->irq_reset_reg);
251 }
252
253 instance->hardware_stop_delay = HZ / 10; //100ms
254
255 //Set output to 0V
256 outl(0x8000, instance->single_reg);
257 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
258 instance->single_reg - instance->reg_base, 0x8000);
259
260 instance->circ_buf.head = 0;
261 instance->circ_buf.tail = 0;
262 instance->preloaded_count = 0;
263 instance->data_count = 0;
264 instance->single_value = 0x8000;
265 instance->single_value_in_fifo = 0x8000;
266
267 //Set status to signal that device is unconfigured.
268 instance->status = ao_status_none;
269 //Signal reset if user is on wait.
270 wake_up_interruptible_all(&instance->wait_queue);
271
272 ME_SUBDEVICE_EXIT;
273
274 return err;
275}
276
277static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
278 struct file *filep,
279 int channel,
280 int single_config,
281 int ref,
282 int trig_chan,
283 int trig_type, int trig_edge, int flags)
284{
285 me6000_ao_subdevice_t *instance;
286 int err = ME_ERRNO_SUCCESS;
287 uint32_t ctrl;
288 uint32_t sync;
289 unsigned long cpu_flags;
290
291 instance = (me6000_ao_subdevice_t *) subdevice;
292
293 PDEBUG("executed. ID=%d\n", instance->ao_idx);
294
295 // Checking parameters
296 if (flags) {
297 PERROR
298 ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n");
299 return ME_ERRNO_INVALID_FLAGS;
300 }
301
302 if (instance->fifo) { //Stream hardware (with or without fifo)
303 if ((trig_edge == ME_TRIG_TYPE_SW)
304 && (trig_edge != ME_TRIG_EDGE_NONE)) {
305 PERROR
306 ("Invalid trigger edge. Software trigger has not edge.\n");
307 return ME_ERRNO_INVALID_TRIG_EDGE;
308 }
309
310 if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) {
311 switch (trig_edge) {
312 case ME_TRIG_EDGE_ANY:
313 case ME_TRIG_EDGE_RISING:
314 case ME_TRIG_EDGE_FALLING:
315 break;
316
317 default:
318 PERROR("Invalid trigger edge.\n");
319 return ME_ERRNO_INVALID_TRIG_EDGE;
320 }
321 }
322
323 if ((trig_type != ME_TRIG_TYPE_SW)
324 && (trig_type != ME_TRIG_TYPE_EXT_DIGITAL)) {
325 PERROR
326 ("Invalid trigger type. Trigger must be software or digital.\n");
327 return ME_ERRNO_INVALID_TRIG_TYPE;
328 }
329 } else { //Single
330 if (trig_edge != ME_TRIG_EDGE_NONE) {
331 PERROR
332 ("Invalid trigger edge. Single output trigger hasn't own edge.\n");
333 return ME_ERRNO_INVALID_TRIG_EDGE;
334 }
335
336 if (trig_type != ME_TRIG_TYPE_SW) {
337 PERROR
338 ("Invalid trigger type. Trigger must be software.\n");
339 return ME_ERRNO_INVALID_TRIG_TYPE;
340 }
341
342 }
343
344 if ((trig_chan != ME_TRIG_CHAN_DEFAULT)
345 && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) {
346 PERROR("Invalid trigger channel specified.\n");
347 return ME_ERRNO_INVALID_TRIG_CHAN;
348 }
349/*
350 if ((trig_type == ME_TRIG_TYPE_EXT_DIGITAL) && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS))
351 {
352 PERROR("Invalid trigger channel specified. Must be synchronous when digital is choose.\n");
353 return ME_ERRNO_INVALID_TRIG_CHAN;
354 }
355*/
356 if (ref != ME_REF_AO_GROUND) {
357 PERROR
358 ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n");
359 return ME_ERRNO_INVALID_REF;
360 }
361
362 if (single_config != 0) {
363 PERROR
364 ("Invalid single config specified. Only one range for anlog outputs is available.\n");
365 return ME_ERRNO_INVALID_SINGLE_CONFIG;
366 }
367
368 if (channel != 0) {
369 PERROR
370 ("Invalid channel number specified. Analog output have only one channel.\n");
371 return ME_ERRNO_INVALID_CHANNEL;
372 }
373
374 ME_SUBDEVICE_ENTER;
375
376 //Subdevice running in stream mode!
377 if ((instance->status >= ao_status_stream_run_wait)
378 && (instance->status < ao_status_stream_end)) {
379 PERROR("Subdevice is busy.\n");
380 ME_SUBDEVICE_EXIT;
381
382 return ME_ERRNO_SUBDEVICE_BUSY;
383 }
384/// @note For single all calls (config and write) are erasing previous state!
385
386 instance->status = ao_status_none;
387
388 // Correct single mirrors
389 instance->single_value_in_fifo = instance->single_value;
390
391 //Stop device
392 err = ao_stop_immediately(instance);
393 if (err) {
394 PERROR_CRITICAL("FSM IS BUSY!\n");
395 ME_SUBDEVICE_EXIT;
396
397 return ME_ERRNO_SUBDEVICE_BUSY;
398 }
399
400 if (instance->fifo) { // Set control register.
401 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
402 // Set stop bit. Stop streaming mode (If running.).
403 ctrl = inl(instance->ctrl_reg);
404 //Reset all bits.
405 ctrl =
406 ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP;
407 if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) {
408 PINFO("External digital trigger.\n");
409
410 if (trig_edge == ME_TRIG_EDGE_ANY) {
411// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
412 instance->ctrl_trg =
413 ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
414 ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
415 } else if (trig_edge == ME_TRIG_EDGE_FALLING) {
416// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
417 instance->ctrl_trg =
418 ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
419 } else if (trig_edge == ME_TRIG_EDGE_RISING) {
420 instance->ctrl_trg = 0x0;
421 }
422 } else if (trig_type == ME_TRIG_TYPE_SW) {
423 PDEBUG("SOFTWARE TRIGGER\n");
424 instance->ctrl_trg = 0x0;
425 }
426 outl(ctrl, instance->ctrl_reg);
427 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
428 instance->reg_base,
429 instance->ctrl_reg - instance->reg_base, ctrl);
430 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
431 } else {
432 PDEBUG("SOFTWARE TRIGGER\n");
433 }
434
435 // Set preload/synchronization register.
436 spin_lock(instance->preload_reg_lock);
437
438 if (trig_type == ME_TRIG_TYPE_SW) {
439 *instance->preload_flags &=
440 ~(ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx);
441 } else //if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL)
442 {
443 *instance->preload_flags |=
444 ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx;
445 }
446
447 if (trig_chan == ME_TRIG_CHAN_DEFAULT) {
448 *instance->preload_flags &=
449 ~(ME6000_AO_SYNC_HOLD << instance->ao_idx);
450 } else //if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS)
451 {
452 *instance->preload_flags |=
453 ME6000_AO_SYNC_HOLD << instance->ao_idx;
454 }
455
456 //Reset hardware register
457 sync = inl(instance->preload_reg);
458 PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
459 instance->preload_reg - instance->reg_base, sync);
460 sync &= ~(ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx);
461 sync |= ME6000_AO_SYNC_HOLD << instance->ao_idx;
462
463 //Output configured in default mode (safe one)
464 outl(sync, instance->preload_reg);
465 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
466 instance->preload_reg - instance->reg_base, sync);
467 spin_unlock(instance->preload_reg_lock);
468
469 instance->status = ao_status_single_configured;
470
471 ME_SUBDEVICE_EXIT;
472
473 return err;
474}
475
476static int me6000_ao_io_single_read(me_subdevice_t * subdevice,
477 struct file *filep,
478 int channel,
479 int *value, int time_out, int flags)
480{
481 me6000_ao_subdevice_t *instance;
482 int err = ME_ERRNO_SUCCESS;
483
484 unsigned long j;
485 unsigned long delay = 0;
486
487 instance = (me6000_ao_subdevice_t *) subdevice;
488
489 PDEBUG("executed. idx=%d\n", instance->ao_idx);
490
491 if (flags & ~ME_IO_SINGLE_NONBLOCKING) {
492 PERROR("Invalid flag specified. %d\n", flags);
493 return ME_ERRNO_INVALID_FLAGS;
494 }
495
496 if ((instance->status >= ao_status_stream_configured)
497 && (instance->status <= ao_status_stream_end)) {
498 PERROR("Subdevice not configured to work in single mode!\n");
499 return ME_ERRNO_PREVIOUS_CONFIG;
500 }
501
502 if (channel != 0) {
503 PERROR("Invalid channel number specified.\n");
504 return ME_ERRNO_INVALID_CHANNEL;
505 }
506
507 if (time_out < 0) {
508 PERROR("Invalid timeout specified.\n");
509 return ME_ERRNO_INVALID_TIMEOUT;
510 }
511
512 ME_SUBDEVICE_ENTER;
513 if ((!flags) && (instance->status == ao_status_single_run_wait)) { //Blocking mode. Wait for trigger.
514 if (time_out) {
515 delay = (time_out * HZ) / 1000;
516 if (delay == 0)
517 delay = 1;
518 }
519
520 j = jiffies;
521
522 //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
523 wait_event_interruptible_timeout(instance->wait_queue,
524 (instance->status !=
525 ao_status_single_run_wait),
526 (delay) ? delay : LONG_MAX);
527
528 if (instance->status == ao_status_none) {
529 PDEBUG("Single canceled.\n");
530 err = ME_ERRNO_CANCELLED;
531 }
532
533 if (signal_pending(current)) {
534 PERROR("Wait on start of state machine interrupted.\n");
535 instance->status = ao_status_none;
536 ao_stop_immediately(instance);
537 err = ME_ERRNO_SIGNAL;
538 }
539
540 if ((delay) && ((jiffies - j) >= delay)) {
541 PDEBUG("Timeout reached.\n");
542 err = ME_ERRNO_TIMEOUT;
543 }
544
545 *value =
546 (!err) ? instance->single_value_in_fifo : instance->
547 single_value;
548 } else { //Non-blocking mode
549 //Read value
550 *value = instance->single_value;
551 }
552
553 ME_SUBDEVICE_EXIT;
554
555 return err;
556}
557
558static int me6000_ao_io_single_write(me_subdevice_t * subdevice,
559 struct file *filep,
560 int channel,
561 int value, int time_out, int flags)
562{
563 me6000_ao_subdevice_t *instance;
564 int err = ME_ERRNO_SUCCESS;
565 unsigned long cpu_flags;
566 unsigned long j;
567 unsigned long delay = 0;
568
569 uint32_t sync_mask;
570 uint32_t mode;
571
572 uint32_t tmp;
573
574/// Workaround for mix-mode - begin
575 uint32_t ctrl = 0x0;
576 uint32_t status;
577/// Workaround for mix-mode - end
578
579 instance = (me6000_ao_subdevice_t *) subdevice;
580
581 PDEBUG("executed. idx=%d\n", instance->ao_idx);
582
583 if (flags &
584 ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS |
585 ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
586 PERROR("Invalid flag specified.\n");
587 return ME_ERRNO_INVALID_FLAGS;
588 }
589
590 if ((instance->status == ao_status_none)
591 || (instance->status > ao_status_single_end)) {
592 PERROR("Subdevice not configured to work in single mode!\n");
593 return ME_ERRNO_PREVIOUS_CONFIG;
594 }
595
596 if (channel != 0) {
597 PERROR("Invalid channel number specified.\n");
598 return ME_ERRNO_INVALID_CHANNEL;
599 }
600
601 if (value & ~ME6000_AO_MAX_DATA) {
602 PERROR("Invalid value provided.\n");
603 return ME_ERRNO_VALUE_OUT_OF_RANGE;
604 }
605
606 if (time_out < 0) {
607 PERROR("Invalid timeout specified.\n");
608 return ME_ERRNO_INVALID_TIMEOUT;
609 }
610
611 ME_SUBDEVICE_ENTER;
612
613/// @note For single all calls (config and write) are erasing previous state!
614
615 //Cancel control task
616 PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
617 instance->ao_control_task_flag = 0;
618 cancel_delayed_work(&instance->ao_control_task);
619
620 // Correct single mirrors
621 instance->single_value_in_fifo = instance->single_value;
622
623 //Stop device
624 err = ao_stop_immediately(instance);
625 if (err) {
626 PERROR_CRITICAL("FSM IS BUSY!\n");
627 ME_SUBDEVICE_EXIT;
628
629 return ME_ERRNO_SUBDEVICE_BUSY;
630 }
631
632 if (time_out) {
633 delay = (time_out * HZ) / 1000;
634
635 if (delay == 0)
636 delay = 1;
637 }
638
639 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
640
641 instance->single_value_in_fifo = value;
642
643 if (instance->fifo) {
644 ctrl = inl(instance->ctrl_reg);
645 }
646
647 if (instance->fifo & ME6000_AO_HAS_FIFO) { /// Workaround for mix-mode - begin
648 //Set speed
649 outl(ME6000_AO_MIN_CHAN_TICKS - 1, instance->timer_reg);
650 PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%x\n",
651 instance->reg_base,
652 instance->timer_reg - instance->reg_base,
653 (int)ME6000_AO_MIN_CHAN_TICKS);
654 instance->hardware_stop_delay = HZ / 10; //100ms
655
656 status = inl(instance->status_reg);
657
658 //Set the continous mode.
659 ctrl &= ~ME6000_AO_CTRL_MODE_MASK;
660 ctrl |= ME6000_AO_MODE_CONTINUOUS;
661
662 //Prepare FIFO
663 if (!(ctrl & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO wasn't enabeled. Do it.
664 PINFO("Enableing FIFO.\n");
665 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
666 ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
667 } else { //Check if FIFO is empty
668 if (status & ME6000_AO_STATUS_BIT_EF) { //FIFO not empty
669 PINFO("Reseting FIFO.\n");
670 ctrl &=
671 ~(ME6000_AO_CTRL_BIT_ENABLE_FIFO |
672 ME6000_AO_CTRL_BIT_ENABLE_IRQ);
673 outl(ctrl, instance->ctrl_reg);
674 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
675 instance->reg_base,
676 instance->ctrl_reg -
677 instance->reg_base, ctrl);
678
679 ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
680 } else { //FIFO empty, only interrupt needs to be disabled!
681 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
682 }
683 }
684
685 outl(ctrl, instance->ctrl_reg);
686 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
687 instance->reg_base,
688 instance->ctrl_reg - instance->reg_base, ctrl);
689
690 //Reset interrupt latch
691 inl(instance->irq_reset_reg);
692
693 //Write output - 1 value to FIFO
694 if (instance->ao_idx & 0x1) {
695 outl(value <<= 16, instance->fifo_reg);
696 PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
697 instance->reg_base,
698 instance->fifo_reg - instance->reg_base,
699 value <<= 16);
700 } else {
701 outl(value, instance->fifo_reg);
702 PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
703 instance->reg_base,
704 instance->fifo_reg - instance->reg_base,
705 value);
706 }
707 /// Workaround for mix-mode - end
708 } else { //No FIFO - always in single mode
709 //Write value
710 PDEBUG("Write value\n");
711 outl(value, instance->single_reg);
712 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
713 instance->reg_base,
714 instance->single_reg - instance->reg_base, value);
715 }
716
717 mode = *instance->preload_flags >> instance->ao_idx;
718 mode &= (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG);
719
720 PINFO("Triggering mode: 0x%08x\n", mode);
721
722 spin_lock(instance->preload_reg_lock);
723 sync_mask = inl(instance->preload_reg);
724 PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
725 instance->preload_reg - instance->reg_base, sync_mask);
726 switch (mode) {
727 case 0: //0x00000000: Individual software
728 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
729
730 if (instance->fifo & ME6000_AO_HAS_FIFO) { // FIFO - Continous mode
731 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
732 if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode.
733 sync_mask &=
734 ~((ME6000_AO_SYNC_EXT_TRIG |
735 ME6000_AO_SYNC_HOLD) << instance->
736 ao_idx);
737
738 outl(sync_mask, instance->preload_reg);
739 PDEBUG_REG
740 ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
741 instance->reg_base,
742 instance->preload_reg - instance->reg_base,
743 sync_mask);
744 }
745 } else { // No FIFO - Single mode: In this case resetting 'ME6000_AO_SYNC_HOLD' will trigger output.
746 if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME6000_AO_SYNC_HOLD) { //Now we can set correct mode. This is exception. It is set to synchronous and triggered later.
747 sync_mask &=
748 ~(ME6000_AO_SYNC_EXT_TRIG << instance->
749 ao_idx);
750 sync_mask |=
751 ME6000_AO_SYNC_HOLD << instance->ao_idx;
752
753 outl(sync_mask, instance->preload_reg);
754 PDEBUG_REG
755 ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
756 instance->reg_base,
757 instance->preload_reg - instance->reg_base,
758 sync_mask);
759 }
760 }
761 instance->single_value = value;
762 break;
763
764 case ME6000_AO_SYNC_EXT_TRIG: //0x00010000: Individual hardware
765 PDEBUG("DIGITAL TRIGGER\n");
766 ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
767
768 if (instance->fifo & ME6000_AO_HAS_FIFO) { // FIFO - Continous mode
769 if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode.
770 sync_mask &=
771 ~((ME6000_AO_SYNC_EXT_TRIG |
772 ME6000_AO_SYNC_HOLD) << instance->
773 ao_idx);
774
775 outl(sync_mask, instance->preload_reg);
776 PDEBUG_REG
777 ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
778 instance->reg_base,
779 instance->preload_reg - instance->reg_base,
780 sync_mask);
781 }
782 } else { // No FIFO - Single mode
783 if ((sync_mask &
784 ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
785 instance->ao_idx)) != ME6000_AO_SYNC_HOLD) {
786 //Now we can set correct mode
787 sync_mask &=
788 ~(ME6000_AO_SYNC_EXT_TRIG << instance->
789 ao_idx);
790 sync_mask |=
791 ME6000_AO_SYNC_HOLD << instance->ao_idx;
792
793 outl(sync_mask, instance->preload_reg);
794 PDEBUG_REG
795 ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
796 instance->reg_base,
797 instance->preload_reg - instance->reg_base,
798 sync_mask);
799 }
800 }
801 break;
802
803 case ME6000_AO_SYNC_HOLD: //0x00000001: Synchronous software
804 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
805
806 if ((sync_mask &
807 ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
808 instance->ao_idx)) !=
809 (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG)) {
810 //Now we can set correct mode
811 sync_mask |=
812 ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx;
813 sync_mask |= ME6000_AO_SYNC_HOLD << instance->ao_idx;
814 outl(sync_mask, instance->preload_reg);
815 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
816 instance->reg_base,
817 instance->preload_reg - instance->reg_base,
818 sync_mask);
819 }
820 //Set triggering flag
821 *instance->triggering_flags |= 0x1 << instance->ao_idx;
822 break;
823
824 case (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG): //0x00010001: Synchronous hardware
825 PDEBUG("DIGITAL TRIGGER\n");
826 ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
827
828 if ((sync_mask &
829 ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
830 instance->ao_idx)) !=
831 (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG)) {
832 //Now we can set correct mode
833 sync_mask |=
834 (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
835 instance->ao_idx;
836 outl(sync_mask, instance->preload_reg);
837 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
838 instance->reg_base,
839 instance->preload_reg - instance->reg_base,
840 sync_mask);
841 }
842 //Set triggering flag
843 *instance->triggering_flags |= 0x1 << instance->ao_idx;
844 break;
845 }
846// spin_unlock(instance->preload_reg_lock); // Moved down.
847
848 if (instance->fifo) { //Activate ISM (remove 'stop' bits)
849 ctrl &=
850 ~(ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
851 ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
852 ctrl |= instance->ctrl_trg;
853 ctrl &=
854 ~(ME6000_AO_CTRL_BIT_STOP |
855 ME6000_AO_CTRL_BIT_IMMEDIATE_STOP);
856
857 outl(ctrl, instance->ctrl_reg);
858 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
859 instance->reg_base,
860 instance->ctrl_reg - instance->reg_base, ctrl);
861 }
862 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
863
864/// @note When flag 'ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS' is set than output is triggered. ALWAYS!
865
866 PINFO("<%s> start mode= 0x%08x %s\n", __FUNCTION__, mode,
867 (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) ? "SYNCHRONOUS" :
868 "");
869 if (instance->fifo & ME6000_AO_HAS_FIFO) { // FIFO - Continous mode
870 if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs
871 //Add channel to start list
872 outl(sync_mask |
873 (ME6000_AO_SYNC_HOLD << instance->ao_idx),
874 instance->preload_reg);
875 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
876 instance->reg_base,
877 instance->preload_reg - instance->reg_base,
878 sync_mask | (ME6000_AO_SYNC_HOLD <<
879 instance->ao_idx));
880
881 //Fire
882 PINFO
883 ("Fired all software synchronous outputs by software trigger.\n");
884 outl(0x8000, instance->single_reg);
885 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
886 instance->reg_base,
887 instance->single_reg - instance->reg_base,
888 0x8000);
889
890 //Restore save settings
891 outl(sync_mask, instance->preload_reg);
892 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
893 instance->reg_base,
894 instance->preload_reg - instance->reg_base,
895 sync_mask);
896
897 } else if (!mode) { //Trigger outputs
898/* //Remove channel from start list
899 outl(sync_mask & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
900 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx));
901*/
902 //Fire
903 PINFO("Software trigger.\n");
904 outl(0x8000, instance->single_reg);
905 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
906 instance->reg_base,
907 instance->single_reg - instance->reg_base,
908 0x8000);
909
910/* //Restore save settings
911 outl(sync_mask, instance->preload_reg);
912 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask);
913*/
914 }
915/// @note This is mix-mode case. For now I do not have possibility to trigger first 4 channels (continous mode) and other (single) ones at once.
916/// @note Because triggering is not working it can not be add to synchronous list. First 4 channels don't need this information, anyway.
917 *instance->triggering_flags &= 0xFFFFFFF0;
918 } else { // No FIFO - Single mode
919 if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Fired all software synchronous outputs.
920 tmp = ~(*instance->preload_flags | 0xFFFF0000);
921 PINFO
922 ("Fired all software synchronous outputs. mask:0x%08x\n",
923 tmp);
924 tmp |= sync_mask & 0xFFFF0000;
925 // Add this channel to list
926 tmp &= ~(ME6000_AO_SYNC_HOLD << instance->ao_idx);
927
928 //Fire
929 PINFO("Software trigger.\n");
930 outl(tmp, instance->preload_reg);
931 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
932 instance->reg_base,
933 instance->preload_reg - instance->reg_base,
934 tmp);
935
936 //Restore save settings
937 outl(sync_mask, instance->preload_reg);
938 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
939 instance->reg_base,
940 instance->preload_reg - instance->reg_base,
941 sync_mask);
942
943 //Set all as triggered.
944 *instance->triggering_flags = 0x0;
945 } else if (!mode) { // Add this channel to list
946 outl(sync_mask &
947 ~(ME6000_AO_SYNC_HOLD << instance->ao_idx),
948 instance->preload_reg);
949 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
950 instance->reg_base,
951 instance->preload_reg - instance->reg_base,
952 sync_mask & ~(ME6000_AO_SYNC_HOLD <<
953 instance->ao_idx));
954
955 //Fire
956 PINFO("Software trigger.\n");
957
958 //Restore save settings
959 outl(sync_mask, instance->preload_reg);
960 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
961 instance->reg_base,
962 instance->preload_reg - instance->reg_base,
963 sync_mask);
964
965 //Set all as triggered.
966 *instance->triggering_flags = 0x0;
967 }
968
969 }
970 spin_unlock(instance->preload_reg_lock);
971
972 instance->status = ao_status_single_run_wait;
973
974 instance->timeout.delay = delay;
975 instance->timeout.start_time = jiffies;
976 instance->ao_control_task_flag = 1;
977 queue_delayed_work(instance->me6000_workqueue,
978 &instance->ao_control_task, 1);
979
980 if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
981 j = jiffies;
982
983 //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
984 wait_event_interruptible_timeout(instance->wait_queue,
985 (instance->status !=
986 ao_status_single_run_wait),
987 (delay) ? delay +
988 1 : LONG_MAX);
989
990 if (instance->status != ao_status_single_end) {
991 PDEBUG("Single canceled.\n");
992 err = ME_ERRNO_CANCELLED;
993 }
994
995 if (signal_pending(current)) {
996 PERROR("Wait on start of state machine interrupted.\n");
997 instance->ao_control_task_flag = 0;
998 cancel_delayed_work(&instance->ao_control_task);
999 ao_stop_immediately(instance);
1000 instance->status = ao_status_none;
1001 err = ME_ERRNO_SIGNAL;
1002 }
1003
1004 if ((delay) && ((jiffies - j) >= delay)) {
1005 if (instance->status == ao_status_single_end) {
1006 PDEBUG("Timeout reached.\n");
1007 } else if ((jiffies - j) > delay) {
1008 PERROR
1009 ("Timeout reached. Not handled by control task!\n");
1010 ao_stop_immediately(instance);
1011 } else {
1012 PERROR
1013 ("Timeout reached. Signal come but status is strange: %d\n",
1014 instance->status);
1015 ao_stop_immediately(instance);
1016 }
1017
1018 instance->ao_control_task_flag = 0;
1019 cancel_delayed_work(&instance->ao_control_task);
1020 instance->status = ao_status_single_end;
1021 err = ME_ERRNO_TIMEOUT;
1022 }
1023 }
1024
1025 ME_SUBDEVICE_EXIT;
1026
1027 return err;
1028}
1029
1030static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
1031 struct file *filep,
1032 meIOStreamConfig_t * config_list,
1033 int count,
1034 meIOStreamTrigger_t * trigger,
1035 int fifo_irq_threshold, int flags)
1036{
1037 me6000_ao_subdevice_t *instance;
1038 int err = ME_ERRNO_SUCCESS;
1039 uint32_t ctrl;
1040 unsigned long cpu_flags;
1041 uint64_t conv_ticks;
1042 unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
1043 unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
1044
1045 instance = (me6000_ao_subdevice_t *) subdevice;
1046
1047 PDEBUG("executed. idx=%d\n", instance->ao_idx);
1048
1049 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
1050 PERROR("Not a streaming ao.\n");
1051 return ME_ERRNO_NOT_SUPPORTED;
1052 }
1053
1054 conv_ticks =
1055 (uint64_t) conv_start_ticks_low +
1056 ((uint64_t) conv_start_ticks_high << 32);
1057
1058 if (flags &
1059 ~(ME_IO_STREAM_CONFIG_HARDWARE_ONLY |
1060 ME_IO_STREAM_CONFIG_WRAPAROUND)) {
1061 PERROR("Invalid flags.\n");
1062 return ME_ERRNO_INVALID_FLAGS;
1063 }
1064
1065 if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
1066 if (!flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
1067 PERROR
1068 ("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n");
1069 return ME_ERRNO_INVALID_FLAGS;
1070 }
1071
1072 if ((trigger->iAcqStopTrigType != ME_TRIG_TYPE_NONE)
1073 || (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE)) {
1074 PERROR
1075 ("Hardware wraparound mode must be in infinite mode.\n");
1076 return ME_ERRNO_INVALID_FLAGS;
1077 }
1078 }
1079
1080 if (count != 1) {
1081 PERROR("Only 1 entry in config list acceptable.\n");
1082 return ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
1083 }
1084
1085 if (config_list[0].iChannel != 0) {
1086 PERROR("Invalid channel number specified.\n");
1087 return ME_ERRNO_INVALID_CHANNEL;
1088 }
1089
1090 if (config_list[0].iStreamConfig != 0) {
1091 PERROR("Only one range available.\n");
1092 return ME_ERRNO_INVALID_STREAM_CONFIG;
1093 }
1094
1095 if (config_list[0].iRef != ME_REF_AO_GROUND) {
1096 PERROR("Output is referenced to ground.\n");
1097 return ME_ERRNO_INVALID_REF;
1098 }
1099
1100 if ((trigger->iAcqStartTicksLow != 0)
1101 || (trigger->iAcqStartTicksHigh != 0)) {
1102 PERROR
1103 ("Invalid acquisition start trigger argument specified.\n");
1104 return ME_ERRNO_INVALID_ACQ_START_ARG;
1105 }
1106
1107 if (config_list[0].iFlags) {
1108 PERROR("Invalid config list flag.\n");
1109 return ME_ERRNO_INVALID_FLAGS;
1110 }
1111
1112 if ((trigger->iAcqStartTrigType != ME_TRIG_TYPE_SW)
1113 && (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_DIGITAL)) {
1114 PERROR("Invalid acquisition start trigger type specified.\n");
1115 return ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
1116 }
1117
1118 if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) {
1119 switch (trigger->iAcqStartTrigEdge) {
1120 case ME_TRIG_EDGE_RISING:
1121 case ME_TRIG_EDGE_FALLING:
1122 case ME_TRIG_EDGE_ANY:
1123 break;
1124
1125 default:
1126 PERROR
1127 ("Invalid acquisition start trigger edge specified.\n");
1128 return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
1129 }
1130 }
1131
1132 if ((trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW)
1133 && (trigger->iAcqStartTrigEdge != ME_TRIG_TYPE_NONE)) {
1134 PERROR("Invalid acquisition start trigger edge specified.\n");
1135 return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
1136 }
1137
1138 if (trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW) {
1139 PERROR("Invalid scan start trigger type specified.\n");
1140 return ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
1141 }
1142
1143 if (trigger->iConvStartTrigType != ME_TRIG_TYPE_TIMER) {
1144 PERROR("Invalid conv start trigger type specified.\n");
1145 return ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
1146 }
1147
1148 if ((conv_ticks < ME6000_AO_MIN_CHAN_TICKS)
1149 || (conv_ticks > ME6000_AO_MAX_CHAN_TICKS)) {
1150 PERROR("Invalid conv start trigger argument specified.\n");
1151 return ME_ERRNO_INVALID_CONV_START_ARG;
1152 }
1153
1154 if (trigger->iAcqStartTicksLow || trigger->iAcqStartTicksHigh) {
1155 PERROR("Invalid acq start trigger argument specified.\n");
1156 return ME_ERRNO_INVALID_ACQ_START_ARG;
1157 }
1158
1159 if (trigger->iScanStartTicksLow || trigger->iScanStartTicksHigh) {
1160 PERROR("Invalid scan start trigger argument specified.\n");
1161 return ME_ERRNO_INVALID_SCAN_START_ARG;
1162 }
1163
1164 switch (trigger->iScanStopTrigType) {
1165 case ME_TRIG_TYPE_NONE:
1166 if (trigger->iScanStopCount != 0) {
1167 PERROR("Invalid scan stop count specified.\n");
1168 return ME_ERRNO_INVALID_SCAN_STOP_ARG;
1169 }
1170 break;
1171
1172 case ME_TRIG_TYPE_COUNT:
1173 if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
1174 if (trigger->iScanStopCount <= 0) {
1175 PERROR("Invalid scan stop count specified.\n");
1176 return ME_ERRNO_INVALID_SCAN_STOP_ARG;
1177 }
1178 } else {
1179 PERROR("The continous mode has not 'scan' contects.\n");
1180 return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1181 }
1182 break;
1183
1184 default:
1185 PERROR("Invalid scan stop trigger type specified.\n");
1186 return ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
1187 }
1188
1189 switch (trigger->iAcqStopTrigType) {
1190 case ME_TRIG_TYPE_NONE:
1191 if (trigger->iAcqStopCount != 0) {
1192 PERROR("Invalid acq stop count specified.\n");
1193 return ME_ERRNO_INVALID_ACQ_STOP_ARG;
1194 }
1195 break;
1196
1197 case ME_TRIG_TYPE_COUNT:
1198 if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
1199 PERROR("Invalid acq stop trigger type specified.\n");
1200 return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1201 }
1202
1203 if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
1204 if (trigger->iAcqStopCount <= 0) {
1205 PERROR
1206 ("The continous mode has not 'scan' contects.\n");
1207 return ME_ERRNO_INVALID_ACQ_STOP_ARG;
1208 }
1209 }
1210// else
1211// {
1212// PERROR("Invalid acq stop trigger type specified.\n");
1213// return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1214// }
1215
1216 break;
1217
1218 default:
1219 PERROR("Invalid acq stop trigger type specified.\n");
1220 return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
1221 }
1222
1223 switch (trigger->iAcqStartTrigChan) {
1224 case ME_TRIG_CHAN_DEFAULT:
1225 case ME_TRIG_CHAN_SYNCHRONOUS:
1226 break;
1227
1228 default:
1229 PERROR("Invalid acq start trigger channel specified.\n");
1230 return ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
1231 }
1232
1233 ME_SUBDEVICE_ENTER;
1234
1235 //Stop device
1236
1237 //Cancel control task
1238 PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
1239 instance->ao_control_task_flag = 0;
1240 cancel_delayed_work(&instance->ao_control_task);
1241
1242 //Check if state machine is stopped.
1243 err = ao_stop_immediately(instance);
1244 if (err) {
1245 PERROR_CRITICAL("FSM IS BUSY!\n");
1246 ME_SUBDEVICE_EXIT;
1247
1248 return ME_ERRNO_SUBDEVICE_BUSY;
1249 }
1250
1251 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
1252 //Reset control register. Block all actions. Disable IRQ. Disable FIFO.
1253 ctrl = ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP;
1254 outl(ctrl, instance->ctrl_reg);
1255 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1256 instance->ctrl_reg - instance->reg_base, ctrl);
1257
1258 //Reset interrupt latch
1259 inl(instance->irq_reset_reg);
1260
1261 //This is paranoic, but to be sure.
1262 instance->preloaded_count = 0;
1263 instance->data_count = 0;
1264 instance->circ_buf.head = 0;
1265 instance->circ_buf.tail = 0;
1266
1267 /* Set mode. */
1268 if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { //Wraparound
1269 if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) { //Hardware wraparound
1270 PINFO("Hardware wraparound.\n");
1271 ctrl |= ME6000_AO_MODE_WRAPAROUND;
1272 instance->mode = ME6000_AO_HW_WRAP_MODE;
1273 } else { //Software wraparound
1274 PINFO("Software wraparound.\n");
1275 ctrl |= ME6000_AO_MODE_CONTINUOUS;
1276 instance->mode = ME6000_AO_SW_WRAP_MODE;
1277 }
1278 } else { //Continous
1279 PINFO("Continous.\n");
1280 ctrl |= ME6000_AO_MODE_CONTINUOUS;
1281 instance->mode = ME6000_AO_CONTINOUS;
1282 }
1283
1284 //Set the trigger edge.
1285 if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Set the trigger type and edge for external trigger.
1286 PINFO("External digital trigger.\n");
1287 instance->start_mode = ME6000_AO_EXT_TRIG;
1288
1289 switch (trigger->iAcqStartTrigEdge) {
1290 case ME_TRIG_EDGE_RISING:
1291 PINFO("Set the trigger edge: rising.\n");
1292 instance->ctrl_trg = 0x0;
1293 break;
1294
1295 case ME_TRIG_EDGE_FALLING:
1296 PINFO("Set the trigger edge: falling.\n");
1297// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
1298 instance->ctrl_trg = ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
1299 break;
1300
1301 case ME_TRIG_EDGE_ANY:
1302 PINFO("Set the trigger edge: both edges.\n");
1303// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
1304 instance->ctrl_trg =
1305 ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
1306 ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
1307 break;
1308 }
1309 } else {
1310 PINFO("Internal software trigger.\n");
1311 instance->start_mode = 0;
1312 }
1313
1314 //Set the stop mode and value.
1315 if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of data
1316 instance->stop_mode = ME6000_AO_ACQ_STOP_MODE;
1317 instance->stop_count = trigger->iAcqStopCount;
1318 } else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of 'scans'
1319 instance->stop_mode = ME6000_AO_SCAN_STOP_MODE;
1320 instance->stop_count = trigger->iScanStopCount;
1321 } else { //Infinite
1322 instance->stop_mode = ME6000_AO_INF_STOP_MODE;
1323 instance->stop_count = 0;
1324 }
1325
1326 PINFO("Stop count: %d.\n", instance->stop_count);
1327
1328 if (trigger->iAcqStartTrigChan == ME_TRIG_CHAN_SYNCHRONOUS) { //Synchronous start
1329 instance->start_mode |= ME6000_AO_SYNC_HOLD;
1330 if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Externaly triggered
1331 PINFO("Synchronous start. Externaly trigger active.\n");
1332 instance->start_mode |= ME6000_AO_SYNC_EXT_TRIG;
1333 }
1334#ifdef MEDEBUG_INFO
1335 else {
1336 PINFO
1337 ("Synchronous start. Externaly trigger dissabled.\n");
1338 }
1339#endif
1340
1341 }
1342 //Set speed
1343 outl(conv_ticks - 2, instance->timer_reg);
1344 PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%llx\n", instance->reg_base,
1345 instance->timer_reg - instance->reg_base, conv_ticks - 2);
1346 instance->hardware_stop_delay = (int)(conv_ticks * HZ) / ME6000_AO_BASE_FREQUENCY; //<== MUST be with cast!
1347
1348 // Write the control word
1349 outl(ctrl, instance->ctrl_reg);
1350 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1351 instance->ctrl_reg - instance->reg_base, ctrl);
1352
1353 //Set status.
1354 instance->status = ao_status_stream_configured;
1355 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
1356
1357 ME_SUBDEVICE_EXIT;
1358
1359 return err;
1360}
1361
1362static int me6000_ao_io_stream_new_values(me_subdevice_t * subdevice,
1363 struct file *filep,
1364 int time_out, int *count, int flags)
1365{
1366 me6000_ao_subdevice_t *instance;
1367 int err = ME_ERRNO_SUCCESS;
1368 long t = 0;
1369 long j;
1370
1371 instance = (me6000_ao_subdevice_t *) subdevice;
1372
1373 PDEBUG("executed. idx=%d\n", instance->ao_idx);
1374
1375 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
1376 PERROR("Not a streaming ao.\n");
1377 return ME_ERRNO_NOT_SUPPORTED;
1378 }
1379
1380 if (flags) {
1381 PERROR("Invalid flag specified.\n");
1382 return ME_ERRNO_INVALID_FLAGS;
1383 }
1384
1385 if (!instance->circ_buf.buf) {
1386 PERROR("Circular buffer not exists.\n");
1387 return ME_ERRNO_INTERNAL;
1388 }
1389
1390 if (time_out < 0) {
1391 PERROR("Invalid time_out specified.\n");
1392 return ME_ERRNO_INVALID_TIMEOUT;
1393 }
1394
1395 ME_SUBDEVICE_ENTER;
1396
1397 if (me_circ_buf_space(&instance->circ_buf)) { //The buffer is NOT full.
1398 *count = me_circ_buf_space(&instance->circ_buf);
1399 } else { //The buffer is full.
1400 if (time_out) {
1401 t = (time_out * HZ) / 1000;
1402
1403 if (t == 0)
1404 t = 1;
1405 } else { //Max time.
1406 t = LONG_MAX;
1407 }
1408
1409 *count = 0;
1410
1411 j = jiffies;
1412
1413 //Only runing process will interrupt this call. Interrupts are when FIFO HF is signaled.
1414 wait_event_interruptible_timeout(instance->wait_queue,
1415 ((me_circ_buf_space
1416 (&instance->circ_buf))
1417 || !(inl(instance->status_reg)
1418 &
1419 ME6000_AO_STATUS_BIT_FSM)),
1420 t);
1421
1422 if (!(inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM)) {
1423 PERROR("AO subdevice is not running.\n");
1424 err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
1425 } else if (signal_pending(current)) {
1426 PERROR("Wait on values interrupted from signal.\n");
1427 instance->status = ao_status_none;
1428 ao_stop_immediately(instance);
1429 err = ME_ERRNO_SIGNAL;
1430 } else if ((jiffies - j) >= t) {
1431 PERROR("Wait on values timed out.\n");
1432 err = ME_ERRNO_TIMEOUT;
1433 } else { //Uff... all is good. Inform user about empty space.
1434 *count = me_circ_buf_space(&instance->circ_buf);
1435 }
1436 }
1437
1438 ME_SUBDEVICE_EXIT;
1439
1440 return err;
1441}
1442
1443static int me6000_ao_io_stream_start(me_subdevice_t * subdevice,
1444 struct file *filep,
1445 int start_mode, int time_out, int flags)
1446{
1447 me6000_ao_subdevice_t *instance;
1448 int err = ME_ERRNO_SUCCESS;
1449 unsigned long cpu_flags = 0;
1450 uint32_t status;
1451 uint32_t ctrl;
1452 uint32_t synch;
1453 int count = 0;
1454 int circ_buffer_count;
1455
1456 unsigned long ref;
1457 unsigned long delay = 0;
1458
1459 instance = (me6000_ao_subdevice_t *) subdevice;
1460
1461 PDEBUG("executed. idx=%d\n", instance->ao_idx);
1462
1463 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
1464 PERROR("Not a streaming ao.\n");
1465 return ME_ERRNO_NOT_SUPPORTED;
1466 }
1467
1468 if (flags & ~ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
1469 PERROR("Invalid flags.\n");
1470 return ME_ERRNO_INVALID_FLAGS;
1471 }
1472
1473 if (time_out < 0) {
1474 PERROR("Invalid timeout specified.\n");
1475 return ME_ERRNO_INVALID_TIMEOUT;
1476 }
1477
1478 if ((start_mode != ME_START_MODE_BLOCKING)
1479 && (start_mode != ME_START_MODE_NONBLOCKING)) {
1480 PERROR("Invalid start mode specified.\n");
1481 return ME_ERRNO_INVALID_START_MODE;
1482 }
1483
1484 if (time_out) {
1485 delay = (time_out * HZ) / 1000;
1486 if (delay == 0)
1487 delay = 1;
1488 }
1489
1490 switch (instance->status) { //Checking actual mode.
1491 case ao_status_stream_configured:
1492 case ao_status_stream_end:
1493 //Correct modes!
1494 break;
1495
1496 //The device is in wrong mode.
1497 case ao_status_none:
1498 case ao_status_single_configured:
1499 case ao_status_single_run_wait:
1500 case ao_status_single_run:
1501 case ao_status_single_end_wait:
1502 PERROR
1503 ("Subdevice must be preinitialize correctly for streaming.\n");
1504 return ME_ERRNO_PREVIOUS_CONFIG;
1505
1506 case ao_status_stream_fifo_error:
1507 case ao_status_stream_buffer_error:
1508 case ao_status_stream_error:
1509 PDEBUG("Before restart broke stream 'STOP' must be caled.\n");
1510 return ME_STATUS_ERROR;
1511
1512 case ao_status_stream_run_wait:
1513 case ao_status_stream_run:
1514 case ao_status_stream_end_wait:
1515 PDEBUG("Stream is already working.\n");
1516 return ME_ERRNO_SUBDEVICE_BUSY;
1517
1518 default:
1519 instance->status = ao_status_stream_error;
1520 PERROR_CRITICAL("Status is in wrong state!\n");
1521 return ME_ERRNO_INTERNAL;
1522
1523 }
1524
1525 ME_SUBDEVICE_ENTER;
1526
1527 if (instance->mode == ME6000_AO_CONTINOUS) { //Continous
1528 instance->circ_buf.tail += instance->preloaded_count;
1529 instance->circ_buf.tail &= instance->circ_buf.mask;
1530 }
1531 circ_buffer_count = me_circ_buf_values(&instance->circ_buf);
1532
1533 if (!circ_buffer_count && !instance->preloaded_count) { //No values in buffer
1534 ME_SUBDEVICE_EXIT;
1535 PERROR("No values in buffer!\n");
1536 return ME_ERRNO_LACK_OF_RESOURCES;
1537 }
1538
1539 //Cancel control task
1540 PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
1541 instance->ao_control_task_flag = 0;
1542 cancel_delayed_work(&instance->ao_control_task);
1543
1544 //Stop device
1545 err = ao_stop_immediately(instance);
1546 if (err) {
1547 PERROR_CRITICAL("FSM IS BUSY!\n");
1548 ME_SUBDEVICE_EXIT;
1549
1550 return ME_ERRNO_SUBDEVICE_BUSY;
1551 }
1552 //Set values for single_read()
1553 instance->single_value = ME6000_AO_MAX_DATA + 1;
1554 instance->single_value_in_fifo = ME6000_AO_MAX_DATA + 1;
1555
1556 //Setting stop points
1557 if (instance->stop_mode == ME6000_AO_SCAN_STOP_MODE) {
1558 instance->stop_data_count =
1559 instance->stop_count * circ_buffer_count;
1560 } else {
1561 instance->stop_data_count = instance->stop_count;
1562 }
1563
1564 if ((instance->stop_data_count != 0)
1565 && (instance->stop_data_count < circ_buffer_count)) {
1566 PERROR("More data in buffer than previously set limit!\n");
1567 }
1568
1569 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
1570 ctrl = inl(instance->ctrl_reg);
1571 //Check FIFO
1572 if (!(ctrl & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO wasn't enabeled. Do it. <= This should be done by user call with ME_WRITE_MODE_PRELOAD
1573 PINFO("Enableing FIFO.\n");
1574 ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
1575 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
1576
1577 instance->preloaded_count = 0;
1578 instance->data_count = 0;
1579 } else { //Block IRQ
1580 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
1581 }
1582 outl(ctrl, instance->ctrl_reg);
1583 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1584 instance->ctrl_reg - instance->reg_base, ctrl);
1585
1586 //Reset interrupt latch
1587 inl(instance->irq_reset_reg);
1588
1589 //Fill FIFO <= Generaly this should be done by user pre-load call but this is second place to do it.
1590 status = inl(instance->status_reg);
1591 if (!(status & ME6000_AO_STATUS_BIT_EF)) { //FIFO empty
1592 if (instance->stop_data_count != 0) {
1593 count = ME6000_AO_FIFO_COUNT;
1594 } else {
1595 count =
1596 (ME6000_AO_FIFO_COUNT <
1597 instance->
1598 stop_data_count) ? ME6000_AO_FIFO_COUNT :
1599 instance->stop_data_count;
1600 }
1601
1602 //Copy data
1603 count =
1604 ao_write_data(instance, count, instance->preloaded_count);
1605
1606 if (count < 0) { //This should never happend!
1607 PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
1608 spin_unlock_irqrestore(&instance->subdevice_lock,
1609 cpu_flags);
1610 ME_SUBDEVICE_EXIT;
1611 return ME_ERRNO_INTERNAL;
1612 }
1613 }
1614 //Set pre-load features.
1615 spin_lock(instance->preload_reg_lock);
1616 synch = inl(instance->preload_reg);
1617 synch &=
1618 ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->
1619 ao_idx);
1620 synch |=
1621 (instance->start_mode & ~ME6000_AO_EXT_TRIG) << instance->ao_idx;
1622 outl(synch, instance->preload_reg);
1623 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1624 instance->preload_reg - instance->reg_base, synch);
1625 spin_unlock(instance->preload_reg_lock);
1626
1627 //Default count is '0'
1628 if (instance->mode == ME6000_AO_CONTINOUS) { //Continous
1629 instance->preloaded_count = 0;
1630 instance->circ_buf.tail += count;
1631 instance->circ_buf.tail &= instance->circ_buf.mask;
1632 } else { //Wraparound
1633 instance->preloaded_count += count;
1634 instance->data_count += count;
1635
1636 //Special case: Infinite wraparound with less than FIFO datas always should runs in hardware mode.
1637 if ((instance->stop_mode == ME6000_AO_INF_STOP_MODE)
1638 && (circ_buffer_count <= ME6000_AO_FIFO_COUNT)) { //Change to hardware wraparound
1639 PDEBUG
1640 ("Changeing mode from software wraparound to hardware wraparound.\n");
1641 //Copy all data
1642 count =
1643 ao_write_data(instance, circ_buffer_count,
1644 instance->preloaded_count);
1645 ctrl &= ~ME6000_AO_CTRL_MODE_MASK;
1646 ctrl |= ME6000_AO_MODE_WRAPAROUND;
1647 }
1648
1649 if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator.
1650 instance->preloaded_count = 0;
1651 } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend!
1652 PERROR_CRITICAL
1653 ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
1654 spin_unlock_irqrestore(&instance->subdevice_lock,
1655 cpu_flags);
1656 ME_SUBDEVICE_EXIT;
1657 return ME_ERRNO_INTERNAL;
1658 }
1659 }
1660
1661 //Set status to 'wait for start'
1662 instance->status = ao_status_stream_run_wait;
1663
1664 status = inl(instance->status_reg);
1665 //Start state machine and interrupts
1666 PINFO("<%s:%d> Start state machine.\n", __FUNCTION__, __LINE__);
1667 ctrl &= ~(ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP);
1668 if (instance->start_mode == ME6000_AO_EXT_TRIG) {
1669 PDEBUG("DIGITAL TRIGGER\n");
1670 ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
1671 }
1672 if (!(status & ME6000_AO_STATUS_BIT_HF)) { //More than half!
1673 if ((ctrl & ME6000_AO_CTRL_MODE_MASK) == ME6000_AO_MODE_CONTINUOUS) { //Enable IRQ only when hardware_continous is set and FIFO is more than half
1674 PINFO("<%s:%d> Start interrupts.\n", __FUNCTION__,
1675 __LINE__);
1676 ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
1677 }
1678 }
1679 outl(ctrl, instance->ctrl_reg);
1680 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
1681 instance->ctrl_reg - instance->reg_base, ctrl);
1682 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
1683
1684 //Trigger output
1685 PINFO("<%s> start mode= 0x%x %s\n", __FUNCTION__, instance->start_mode,
1686 (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) ? "SYNCHRONOUS" :
1687 "");
1688 if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs
1689 spin_lock(instance->preload_reg_lock);
1690 synch = inl(instance->preload_reg);
1691 //Add channel to start list
1692 outl(synch | (ME6000_AO_SYNC_HOLD << instance->ao_idx),
1693 instance->preload_reg);
1694 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
1695 instance->reg_base,
1696 instance->preload_reg - instance->reg_base,
1697 synch | (ME6000_AO_SYNC_HOLD << instance->ao_idx));
1698
1699 //Fire
1700 PINFO
1701 ("Fired all software synchronous outputs by software trigger.\n");
1702 outl(0x8000, instance->single_reg);
1703 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
1704 instance->reg_base,
1705 instance->single_reg - instance->reg_base, 0x8000);
1706
1707 //Restore save settings
1708 outl(synch, instance->preload_reg);
1709 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
1710 instance->reg_base,
1711 instance->preload_reg - instance->reg_base, synch);
1712 spin_unlock(instance->preload_reg_lock);
1713 } else if (!instance->start_mode) { //Trigger outputs
1714/*
1715 spin_lock(instance->preload_reg_lock);
1716 synch = inl(instance->preload_reg);
1717 //Remove channel from start list
1718 outl(synch & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
1719 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx));
1720*/
1721 //Fire
1722 PINFO("Software trigger.\n");
1723 outl(0x8000, instance->single_reg);
1724 PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
1725 instance->reg_base,
1726 instance->single_reg - instance->reg_base, 0x8000);
1727
1728/*
1729 //Restore save settings
1730 outl(synch, instance->preload_reg);
1731 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch);
1732 spin_unlock(instance->preload_reg_lock);
1733*/
1734 }
1735 // Set control task's timeout
1736 instance->timeout.delay = delay;
1737 instance->timeout.start_time = jiffies;
1738
1739 if (status & ME6000_AO_STATUS_BIT_HF) { //Less than half but not empty!
1740 PINFO("Less than half.\n");
1741 if (instance->stop_data_count == 0) {
1742 count = ME6000_AO_FIFO_COUNT / 2;
1743 } else {
1744 count =
1745 ((ME6000_AO_FIFO_COUNT / 2) <
1746 instance->stop_data_count) ? ME6000_AO_FIFO_COUNT /
1747 2 : instance->stop_data_count;
1748 }
1749
1750 //Copy data
1751 count =
1752 ao_write_data(instance, count, instance->preloaded_count);
1753
1754 if (count < 0) { //This should never happend!
1755 PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
1756 ME_SUBDEVICE_EXIT;
1757 return ME_ERRNO_INTERNAL;
1758 }
1759
1760 if (instance->mode == ME6000_AO_CONTINOUS) { //Continous
1761 instance->circ_buf.tail += count;
1762 instance->circ_buf.tail &= instance->circ_buf.mask;
1763 } else { //Wraparound
1764 instance->data_count += count;
1765 instance->preloaded_count += count;
1766
1767 if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator.
1768 instance->preloaded_count = 0;
1769 } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend!
1770 PERROR_CRITICAL
1771 ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
1772 ME_SUBDEVICE_EXIT;
1773 return ME_ERRNO_INTERNAL;
1774 }
1775 }
1776
1777 status = inl(instance->status_reg);
1778 if (!(status & ME6000_AO_STATUS_BIT_HF)) { //More than half!
1779 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
1780 PINFO("<%s:%d> Start interrupts.\n", __FUNCTION__,
1781 __LINE__);
1782 ctrl = inl(instance->ctrl_reg);
1783 ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
1784 outl(ctrl, instance->ctrl_reg);
1785 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
1786 instance->reg_base,
1787 instance->ctrl_reg - instance->reg_base,
1788 ctrl);
1789 spin_unlock_irqrestore(&instance->subdevice_lock,
1790 cpu_flags);
1791 }
1792 }
1793 //Special case: Limited wraparound with less than HALF FIFO datas need work around to generate first interrupt.
1794 if ((instance->stop_mode != ME6000_AO_INF_STOP_MODE)
1795 && (instance->mode == ME6000_AO_SW_WRAP_MODE)
1796 && (circ_buffer_count <= (ME6000_AO_FIFO_COUNT / 2))) { //Put more data to FIFO
1797 PINFO("Limited wraparound with less than HALF FIFO datas.\n");
1798 if (instance->preloaded_count) { //This should never happend!
1799 PERROR_CRITICAL
1800 ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
1801 ME_SUBDEVICE_EXIT;
1802 return ME_ERRNO_INTERNAL;
1803 }
1804
1805 while (instance->stop_data_count > instance->data_count) { //Maximum data not set jet.
1806 //Copy to buffer
1807 if (circ_buffer_count != ao_write_data(instance, circ_buffer_count, 0)) { //This should never happend!
1808 PERROR_CRITICAL
1809 ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
1810 ME_SUBDEVICE_EXIT;
1811 return ME_ERRNO_INTERNAL;
1812 }
1813 instance->data_count += circ_buffer_count;
1814
1815 if (!((status = inl(instance->status_reg)) & ME6000_AO_STATUS_BIT_HF)) { //FIFO is more than half. Enable IRQ and end copy.
1816 //Reset interrupt latch
1817 inl(instance->irq_reset_reg);
1818
1819 spin_lock_irqsave(&instance->subdevice_lock,
1820 cpu_flags);
1821 PINFO("<%s:%d> Start interrupts.\n",
1822 __FUNCTION__, __LINE__);
1823 ctrl = inl(instance->ctrl_reg);
1824 ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
1825 outl(ctrl, instance->ctrl_reg);
1826 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
1827 instance->reg_base,
1828 instance->ctrl_reg -
1829 instance->reg_base, ctrl);
1830 spin_unlock_irqrestore(&instance->
1831 subdevice_lock,
1832 cpu_flags);
1833 break;
1834 }
1835 }
1836 }
1837 // Schedule control task
1838 instance->ao_control_task_flag = 1;
1839 queue_delayed_work(instance->me6000_workqueue,
1840 &instance->ao_control_task, 1);
1841
1842 if (start_mode == ME_START_MODE_BLOCKING) { //Wait for start.
1843 ref = jiffies;
1844 //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
1845 wait_event_interruptible_timeout(instance->wait_queue,
1846 (instance->status !=
1847 ao_status_stream_run_wait),
1848 (delay) ? delay +
1849 1 : LONG_MAX);
1850
1851 if ((instance->status != ao_status_stream_run)
1852 && (instance->status != ao_status_stream_end)) {
1853 PDEBUG("Starting stream canceled. %d\n",
1854 instance->status);
1855 err = ME_ERRNO_CANCELLED;
1856 }
1857
1858 if (signal_pending(current)) {
1859 PERROR("Wait on start of state machine interrupted.\n");
1860 instance->status = ao_status_none;
1861 ao_stop_immediately(instance);
1862 err = ME_ERRNO_SIGNAL;
1863 }
1864
1865 if ((delay) && ((jiffies - ref) >= delay)) {
1866 if (instance->status != ao_status_stream_run) {
1867 if (instance->status == ao_status_stream_end) {
1868 PDEBUG("Timeout reached.\n");
1869 } else if ((jiffies - ref) > delay) {
1870 PERROR
1871 ("Timeout reached. Not handled by control task!\n");
1872 ao_stop_immediately(instance);
1873 } else {
1874 PERROR
1875 ("Timeout reached. Signal come but status is strange: %d\n",
1876 instance->status);
1877 ao_stop_immediately(instance);
1878 }
1879
1880 instance->ao_control_task_flag = 0;
1881 cancel_delayed_work(&instance->ao_control_task);
1882 instance->status = ao_status_stream_end;
1883 err = ME_ERRNO_TIMEOUT;
1884 }
1885 }
1886 }
1887
1888 ME_SUBDEVICE_EXIT;
1889 return err;
1890}
1891
1892static int me6000_ao_io_stream_status(me_subdevice_t * subdevice,
1893 struct file *filep,
1894 int wait,
1895 int *status, int *values, int flags)
1896{
1897 me6000_ao_subdevice_t *instance;
1898 int err = ME_ERRNO_SUCCESS;
1899
1900 instance = (me6000_ao_subdevice_t *) subdevice;
1901
1902 PDEBUG("executed. idx=%d\n", instance->ao_idx);
1903
1904 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
1905 PERROR("Not a streaming ao.\n");
1906 return ME_ERRNO_NOT_SUPPORTED;
1907 }
1908
1909 if (flags) {
1910 PERROR("Invalid flag specified.\n");
1911 return ME_ERRNO_INVALID_FLAGS;
1912 }
1913
1914 if ((wait != ME_WAIT_NONE) && (wait != ME_WAIT_IDLE)) {
1915 PERROR("Invalid wait argument specified.\n");
1916 *status = ME_STATUS_INVALID;
1917 return ME_ERRNO_INVALID_WAIT;
1918 }
1919
1920 ME_SUBDEVICE_ENTER;
1921
1922 switch (instance->status) {
1923 case ao_status_single_configured:
1924 case ao_status_single_end:
1925 case ao_status_stream_configured:
1926 case ao_status_stream_end:
1927 case ao_status_stream_fifo_error:
1928 case ao_status_stream_buffer_error:
1929 case ao_status_stream_error:
1930 *status = ME_STATUS_IDLE;
1931 break;
1932
1933 case ao_status_single_run_wait:
1934 case ao_status_single_run:
1935 case ao_status_single_end_wait:
1936 case ao_status_stream_run_wait:
1937 case ao_status_stream_run:
1938 case ao_status_stream_end_wait:
1939 *status = ME_STATUS_BUSY;
1940 break;
1941
1942 case ao_status_none:
1943 default:
1944 *status =
1945 (inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM) ?
1946 ME_STATUS_BUSY : ME_STATUS_IDLE;
1947 break;
1948 }
1949
1950 if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) {
1951 //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
1952 wait_event_interruptible_timeout(instance->wait_queue,
1953 ((instance->status !=
1954 ao_status_single_run_wait)
1955 && (instance->status !=
1956 ao_status_single_run)
1957 && (instance->status !=
1958 ao_status_single_end_wait)
1959 && (instance->status !=
1960 ao_status_stream_run_wait)
1961 && (instance->status !=
1962 ao_status_stream_run)
1963 && (instance->status !=
1964 ao_status_stream_end_wait)),
1965 LONG_MAX);
1966
1967 if (instance->status != ao_status_stream_end) {
1968 PDEBUG("Wait for IDLE canceled. %d\n",
1969 instance->status);
1970 err = ME_ERRNO_CANCELLED;
1971 }
1972
1973 if (signal_pending(current)) {
1974 PERROR("Wait for IDLE interrupted.\n");
1975 instance->status = ao_status_none;
1976 ao_stop_immediately(instance);
1977 err = ME_ERRNO_SIGNAL;
1978 }
1979
1980 *status = ME_STATUS_IDLE;
1981 }
1982
1983 *values = me_circ_buf_space(&instance->circ_buf);
1984
1985 ME_SUBDEVICE_EXIT;
1986
1987 return err;
1988}
1989
1990static int me6000_ao_io_stream_stop(me_subdevice_t * subdevice,
1991 struct file *filep,
1992 int stop_mode, int flags)
1993{ /// @note Stop work and empty buffer and FIFO
1994 int err = ME_ERRNO_SUCCESS;
1995 me6000_ao_subdevice_t *instance;
1996 unsigned long cpu_flags;
1997 volatile uint32_t ctrl;
1998
1999 instance = (me6000_ao_subdevice_t *) subdevice;
2000
2001 PDEBUG("executed. idx=%d\n", instance->ao_idx);
2002
2003 if (flags & ~ME_IO_STREAM_STOP_PRESERVE_BUFFERS) {
2004 PERROR("Invalid flag specified.\n");
2005 return ME_ERRNO_INVALID_FLAGS;
2006 }
2007
2008 if ((stop_mode != ME_STOP_MODE_IMMEDIATE)
2009 && (stop_mode != ME_STOP_MODE_LAST_VALUE)) {
2010 PERROR("Invalid stop mode specified.\n");
2011 return ME_ERRNO_INVALID_STOP_MODE;
2012 }
2013
2014 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
2015 PERROR("Not a streaming ao.\n");
2016 return ME_ERRNO_NOT_SUPPORTED;
2017 }
2018
2019 if (instance->status < ao_status_stream_configured) {
2020 //There is nothing to stop!
2021 PERROR("Subdevice not in streaming mode. %d\n",
2022 instance->status);
2023 return ME_ERRNO_PREVIOUS_CONFIG;
2024 }
2025
2026 ME_SUBDEVICE_ENTER;
2027
2028 //Mark as stopping. => Software stop.
2029 instance->status = ao_status_stream_end_wait;
2030
2031 if (stop_mode == ME_STOP_MODE_IMMEDIATE) { //Stopped now!
2032 err = ao_stop_immediately(instance);
2033 } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
2034 ctrl = inl(instance->ctrl_reg) & ME6000_AO_CTRL_MODE_MASK;
2035 if (ctrl == ME6000_AO_MODE_WRAPAROUND) { //Hardware wraparound => Hardware stop.
2036 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2037 ctrl = inl(instance->ctrl_reg);
2038 ctrl |= ME6000_AO_CTRL_BIT_STOP;
2039 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
2040 outl(ctrl, instance->ctrl_reg);
2041 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2042 instance->reg_base,
2043 instance->ctrl_reg - instance->reg_base,
2044 ctrl);
2045 spin_unlock_irqrestore(&instance->subdevice_lock,
2046 cpu_flags);
2047
2048 //Reset interrupt latch
2049 inl(instance->irq_reset_reg);
2050 }
2051 //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
2052 wait_event_interruptible_timeout(instance->wait_queue,
2053 (instance->status !=
2054 ao_status_stream_end_wait),
2055 LONG_MAX);
2056
2057 if (instance->status != ao_status_stream_end) {
2058 PDEBUG("Stopping stream canceled.\n");
2059 err = ME_ERRNO_CANCELLED;
2060 }
2061
2062 if (signal_pending(current)) {
2063 PERROR("Stopping stream interrupted.\n");
2064 instance->status = ao_status_none;
2065 ao_stop_immediately(instance);
2066 err = ME_ERRNO_SIGNAL;
2067 }
2068 }
2069
2070 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2071 ctrl = inl(instance->ctrl_reg);
2072 ctrl |= ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
2073 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
2074 if (!flags) { //Reset FIFO
2075 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_FIFO;
2076 }
2077 outl(ctrl, instance->ctrl_reg);
2078 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
2079 instance->ctrl_reg - instance->reg_base, ctrl);
2080 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
2081
2082 //Reset interrupt latch
2083 inl(instance->irq_reset_reg);
2084
2085 if (!flags) { //Reset software buffer
2086 instance->circ_buf.head = 0;
2087 instance->circ_buf.tail = 0;
2088 instance->preloaded_count = 0;
2089 instance->data_count = 0;
2090 }
2091
2092 ME_SUBDEVICE_EXIT;
2093
2094 return err;
2095}
2096
2097static int me6000_ao_io_stream_write(me_subdevice_t * subdevice,
2098 struct file *filep,
2099 int write_mode,
2100 int *values, int *count, int flags)
2101{
2102 int err = ME_ERRNO_SUCCESS;
2103 me6000_ao_subdevice_t *instance;
2104 unsigned long cpu_flags = 0;
2105 uint32_t reg_copy;
2106
2107 int copied_from_user = 0;
2108 int left_to_copy_from_user = *count;
2109
2110 int copied_values;
2111
2112 instance = (me6000_ao_subdevice_t *) subdevice;
2113
2114 PDEBUG("executed. idx=%d\n", instance->ao_idx);
2115
2116 //Checking arguments
2117 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
2118 PERROR("Not a streaming ao.\n");
2119 return ME_ERRNO_NOT_SUPPORTED;
2120 }
2121
2122 if (flags) {
2123 PERROR("Invalid flag specified.\n");
2124 return ME_ERRNO_INVALID_FLAGS;
2125 }
2126
2127 if (*count <= 0) {
2128 PERROR("Invalid count of values specified.\n");
2129 return ME_ERRNO_INVALID_VALUE_COUNT;
2130 }
2131
2132 if (values == NULL) {
2133 PERROR("Invalid address of values specified.\n");
2134 return ME_ERRNO_INVALID_POINTER;
2135 }
2136
2137 if ((instance->status == ao_status_none) || (instance->status == ao_status_single_configured)) { //The device is in single mode.
2138 PERROR
2139 ("Subdevice must be preinitialize correctly for streaming.\n");
2140 return ME_ERRNO_PREVIOUS_CONFIG;
2141 }
2142
2143 switch (write_mode) {
2144 case ME_WRITE_MODE_PRELOAD:
2145
2146 //Device must be stopped.
2147 if ((instance->status != ao_status_stream_configured)
2148 && (instance->status != ao_status_stream_end)) {
2149 PERROR
2150 ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
2151 return ME_ERRNO_PREVIOUS_CONFIG;
2152 }
2153 break;
2154 case ME_WRITE_MODE_NONBLOCKING:
2155 case ME_WRITE_MODE_BLOCKING:
2156 /// @note In blocking mode: When device is not runing and there is not enought space call will blocked up!
2157 /// @note Some other thread must empty buffer by strating engine.
2158 break;
2159
2160 default:
2161 PERROR("Invalid write mode specified.\n");
2162 return ME_ERRNO_INVALID_WRITE_MODE;
2163 }
2164
2165 if (instance->mode & ME6000_AO_WRAP_MODE) { //Wraparound mode. Device must be stopped.
2166 if ((instance->status != ao_status_stream_configured)
2167 && (instance->status != ao_status_stream_end)) {
2168 PERROR
2169 ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
2170 return ME_ERRNO_INVALID_WRITE_MODE;
2171 }
2172 }
2173
2174 if ((instance->mode == ME6000_AO_HW_WRAP_MODE)
2175 && (write_mode != ME_WRITE_MODE_PRELOAD)) {
2176/*
2177 PERROR("Only 'pre-load' write is acceptable in hardware wraparound mode.\n");
2178 return ME_ERRNO_PREVIOUS_CONFIG;
2179*/
2180 //This is transparent for user.
2181 PDEBUG("Changing write_mode to ME_WRITE_MODE_PRELOAD.\n");
2182 write_mode = ME_WRITE_MODE_PRELOAD;
2183 }
2184
2185 ME_SUBDEVICE_ENTER;
2186
2187 if (write_mode == ME_WRITE_MODE_PRELOAD) { //Init enviroment - preload
2188 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2189 reg_copy = inl(instance->ctrl_reg);
2190 //Check FIFO
2191 if (!(reg_copy & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO not active. Enable it.
2192 reg_copy |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
2193 outl(reg_copy, instance->ctrl_reg);
2194 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2195 instance->reg_base,
2196 instance->ctrl_reg - instance->reg_base,
2197 reg_copy);
2198 instance->preloaded_count = 0;
2199 }
2200 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
2201 }
2202
2203 while (1) {
2204 //Copy to buffer. This step is common for all modes.
2205 copied_from_user =
2206 ao_get_data_from_user(instance, left_to_copy_from_user,
2207 values + (*count -
2208 left_to_copy_from_user));
2209 left_to_copy_from_user -= copied_from_user;
2210
2211 reg_copy = inl(instance->status_reg);
2212 if ((instance->status == ao_status_stream_run) && !(reg_copy & ME6000_AO_STATUS_BIT_FSM)) { //BROKEN PIPE! The state machine is stoped but logical status show that should be working.
2213 PERROR("Broken pipe in write.\n");
2214 err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
2215 break;
2216 }
2217
2218 if ((instance->status == ao_status_stream_run) && (instance->mode == ME6000_AO_CONTINOUS) && (reg_copy & ME6000_AO_STATUS_BIT_HF)) { //Continous mode runing and data are below half!
2219
2220 // Block interrupts.
2221 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2222 reg_copy = inl(instance->ctrl_reg);
2223 reg_copy &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
2224 outl(reg_copy, instance->ctrl_reg);
2225 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2226 instance->reg_base,
2227 instance->ctrl_reg - instance->reg_base,
2228 reg_copy);
2229 spin_unlock_irqrestore(&instance->subdevice_lock,
2230 cpu_flags);
2231
2232 //Fast copy
2233 copied_values =
2234 ao_write_data(instance, ME6000_AO_FIFO_COUNT / 2,
2235 0);
2236 if (copied_values > 0) {
2237 instance->circ_buf.tail += copied_values;
2238 instance->circ_buf.tail &=
2239 instance->circ_buf.mask;
2240 continue;
2241 }
2242 //Reset interrupt latch
2243 inl(instance->irq_reset_reg);
2244
2245 // Activate interrupts.
2246 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2247 reg_copy = inl(instance->ctrl_reg);
2248 reg_copy |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
2249 outl(reg_copy, instance->ctrl_reg);
2250 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2251 instance->reg_base,
2252 instance->ctrl_reg - instance->reg_base,
2253 reg_copy);
2254 spin_unlock_irqrestore(&instance->subdevice_lock,
2255 cpu_flags);
2256
2257 if (copied_values == 0) { //This was checked and never should happend!
2258 PERROR_CRITICAL("COPY FINISH WITH 0!\n");
2259 }
2260
2261 if (copied_values < 0) { //This was checked and never should happend!
2262 PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
2263 instance->status = ao_status_stream_fifo_error;
2264 err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
2265 break;
2266 }
2267 }
2268
2269 if (!left_to_copy_from_user) { //All datas were copied.
2270 break;
2271 } else { //Not all datas were copied.
2272 if (instance->mode & ME6000_AO_WRAP_MODE) { //Error too much datas! Wraparound is limited in size!
2273 PERROR
2274 ("Too much data for wraparound mode! Exceeded size of %ld.\n",
2275 ME6000_AO_CIRC_BUF_COUNT - 1);
2276 err = ME_ERRNO_RING_BUFFER_OVERFLOW;
2277 break;
2278 }
2279
2280 if (write_mode != ME_WRITE_MODE_BLOCKING) { //Non blocking calls
2281 break;
2282 }
2283
2284 wait_event_interruptible(instance->wait_queue,
2285 me_circ_buf_space(&instance->
2286 circ_buf));
2287
2288 if (signal_pending(current)) {
2289 PERROR("Writing interrupted by signal.\n");
2290 instance->status = ao_status_none;
2291 ao_stop_immediately(instance);
2292 err = ME_ERRNO_SIGNAL;
2293 break;
2294 }
2295
2296 if (instance->status == ao_status_none) { //Reset
2297 PERROR("Writing interrupted by reset.\n");
2298 err = ME_ERRNO_CANCELLED;
2299 break;
2300 }
2301 }
2302 }
2303
2304 if (write_mode == ME_WRITE_MODE_PRELOAD) { //Copy data to FIFO - preload
2305 copied_values =
2306 ao_write_data_pooling(instance, ME6000_AO_FIFO_COUNT,
2307 instance->preloaded_count);
2308 instance->preloaded_count += copied_values;
2309 instance->data_count += copied_values;
2310
2311 if ((instance->mode == ME6000_AO_HW_WRAP_MODE)
2312 && (me_circ_buf_values(&instance->circ_buf) >
2313 ME6000_AO_FIFO_COUNT)) {
2314 PERROR
2315 ("Too much data for hardware wraparound mode! Exceeded size of %d.\n",
2316 ME6000_AO_FIFO_COUNT);
2317 err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
2318 }
2319 }
2320
2321 *count = *count - left_to_copy_from_user;
2322 ME_SUBDEVICE_EXIT;
2323
2324 return err;
2325}
2326
2327#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
2328static irqreturn_t me6000_ao_isr(int irq, void *dev_id)
2329#else
2330static irqreturn_t me6000_ao_isr(int irq, void *dev_id, struct pt_regs *regs)
2331#endif
2332{
2333 me6000_ao_subdevice_t *instance = dev_id;
2334 uint32_t irq_status;
2335 uint32_t ctrl;
2336 uint32_t status;
2337 int count = 0;
2338
2339 PDEBUG("executed. idx=%d\n", instance->ao_idx);
2340
2341 if (irq != instance->irq) {
2342 PERROR("Incorrect interrupt num: %d.\n", irq);
2343 return IRQ_NONE;
2344 }
2345
2346 irq_status = inl(instance->irq_status_reg);
2347 if (!(irq_status & (ME6000_IRQ_STATUS_BIT_AO_HF << instance->ao_idx))) {
2348 PINFO("%ld Shared interrupt. %s(): ID=%d: status_reg=0x%04X\n",
2349 jiffies, __FUNCTION__, instance->ao_idx, irq_status);
2350 return IRQ_NONE;
2351 }
2352
2353 if (!instance->circ_buf.buf) {
2354 instance->status = ao_status_stream_error;
2355 PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n");
2356 //Block interrupts. Stop machine.
2357 ctrl = inl(instance->ctrl_reg);
2358 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
2359 ctrl |=
2360 ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP;
2361 outl(ctrl, instance->ctrl_reg);
2362 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2363 instance->reg_base,
2364 instance->ctrl_reg - instance->reg_base, ctrl);
2365
2366 //Inform user
2367 wake_up_interruptible_all(&instance->wait_queue);
2368 return IRQ_HANDLED;
2369 }
2370
2371 status = inl(instance->status_reg);
2372 if (!(status & ME6000_AO_STATUS_BIT_FSM)) { //Too late. Not working! END? BROKEN PIPE?
2373 /// @note Error checking was moved to separate task.
2374 PDEBUG("Interrupt come but ISM is not working!\n");
2375 //Block interrupts. Stop machine.
2376 ctrl = inl(instance->ctrl_reg);
2377 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
2378 ctrl |=
2379 ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
2380 outl(ctrl, instance->ctrl_reg);
2381 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2382 instance->reg_base,
2383 instance->ctrl_reg - instance->reg_base, ctrl);
2384
2385 //Reset interrupt latch
2386 inl(instance->irq_reset_reg);
2387
2388 /// @note User notification was also moved to separate task.
2389 return IRQ_HANDLED;
2390 }
2391 //General procedure. Process more datas.
2392
2393#ifdef MEDEBUG_DEBUG
2394 if (!me_circ_buf_values(&instance->circ_buf)) { //Buffer is empty!
2395 PDEBUG("Circular buffer empty!\n");
2396 }
2397#endif
2398
2399 //Check FIFO
2400 if (status & ME6000_AO_STATUS_BIT_HF) { //OK less than half
2401
2402 //Block interrupts
2403 ctrl = inl(instance->ctrl_reg);
2404 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
2405 outl(ctrl, instance->ctrl_reg);
2406 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2407 instance->reg_base,
2408 instance->ctrl_reg - instance->reg_base, ctrl);
2409
2410 do {
2411 //Calculate how many should be copied.
2412 count =
2413 (instance->stop_data_count) ? instance->
2414 stop_data_count -
2415 instance->data_count : ME6000_AO_FIFO_COUNT / 2;
2416 if (ME6000_AO_FIFO_COUNT / 2 < count) {
2417 count = ME6000_AO_FIFO_COUNT / 2;
2418 }
2419 //Copy data
2420 if (instance->mode == ME6000_AO_CONTINOUS) { //Continous
2421 count = ao_write_data(instance, count, 0);
2422 if (count > 0) {
2423 instance->circ_buf.tail += count;
2424 instance->circ_buf.tail &=
2425 instance->circ_buf.mask;
2426 instance->data_count += count;
2427
2428 if ((instance->status == ao_status_stream_end_wait) && !me_circ_buf_values(&instance->circ_buf)) { //Stoping. Whole buffer was copied.
2429 break;
2430 }
2431 }
2432 } else if ((instance->mode == ME6000_AO_SW_WRAP_MODE) && ((ctrl & ME6000_AO_CTRL_MODE_MASK) == ME6000_AO_MODE_CONTINUOUS)) { //Wraparound (software)
2433 if (instance->status == ao_status_stream_end_wait) { //We stoping => Copy to the end of the buffer.
2434 count =
2435 ao_write_data(instance, count, 0);
2436 } else { //Copy in wraparound mode.
2437 count =
2438 ao_write_data_wraparound(instance,
2439 count,
2440 instance->
2441 preloaded_count);
2442 }
2443
2444 if (count > 0) {
2445 instance->data_count += count;
2446 instance->preloaded_count += count;
2447 instance->preloaded_count %=
2448 me_circ_buf_values(&instance->
2449 circ_buf);
2450
2451 if ((instance->status == ao_status_stream_end_wait) && !instance->preloaded_count) { //Stoping. Whole buffer was copied.
2452 break;
2453 }
2454 }
2455 }
2456
2457 if ((count <= 0) || (instance->stop_data_count && (instance->stop_data_count <= instance->data_count))) { //End of work.
2458 break;
2459 }
2460 } //Repeat if still is under half fifo
2461 while ((status =
2462 inl(instance->status_reg)) & ME6000_AO_STATUS_BIT_HF);
2463
2464 //Unblock interrupts
2465 ctrl = inl(instance->ctrl_reg);
2466 if (count >= 0) { //Copy was successful.
2467 if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. No more interrupts.
2468 PDEBUG("Finishing work. Interrupt disabled.\n");
2469 instance->status = ao_status_stream_end_wait;
2470 } else if (count > 0) { //Normal work. Enable interrupt.
2471 PDEBUG("Normal work. Enable interrupt.\n");
2472 ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
2473 } else { //Normal work but there are no more data in buffer. Interrupt blocked. stream_write() will unblock it.
2474 PDEBUG
2475 ("No data in software buffer. Interrupt blocked.\n");
2476 }
2477 } else { //Error during copy.
2478 instance->status = ao_status_stream_fifo_error;
2479 }
2480
2481 outl(ctrl, instance->ctrl_reg);
2482 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2483 instance->reg_base,
2484 instance->ctrl_reg - instance->reg_base, ctrl);
2485 } else { //?? more than half
2486 PDEBUG
2487 ("Interrupt come but FIFO more than half full! Reset interrupt.\n");
2488 }
2489
2490 PINFO("ISR: Buffer count: %d.(T:%d H:%d)\n",
2491 me_circ_buf_values(&instance->circ_buf), instance->circ_buf.tail,
2492 instance->circ_buf.head);
2493 PINFO("ISR: Stop count: %d.\n", instance->stop_count);
2494 PINFO("ISR: Stop data count: %d.\n", instance->stop_data_count);
2495 PINFO("ISR: Data count: %d.\n", instance->data_count);
2496
2497 //Reset interrupt latch
2498 inl(instance->irq_reset_reg);
2499
2500 //Inform user
2501 wake_up_interruptible_all(&instance->wait_queue);
2502
2503 return IRQ_HANDLED;
2504}
2505
2506static void me6000_ao_destructor(struct me_subdevice *subdevice)
2507{
2508 me6000_ao_subdevice_t *instance;
2509
2510 instance = (me6000_ao_subdevice_t *) subdevice;
2511
2512 PDEBUG("executed. idx=%d\n", instance->ao_idx);
2513
2514 instance->ao_control_task_flag = 0;
2515
2516 // Reset subdevice to asure clean exit.
2517 me6000_ao_io_reset_subdevice(subdevice, NULL,
2518 ME_IO_RESET_SUBDEVICE_NO_FLAGS);
2519
2520 // Remove any tasks from work queue. This is paranoic because it was done allready in reset().
2521 if (!cancel_delayed_work(&instance->ao_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue.
2522 set_current_state(TASK_INTERRUPTIBLE);
2523 schedule_timeout(2);
2524 }
2525
2526 if (instance->fifo & ME6000_AO_HAS_FIFO) {
2527 if (instance->irq) {
2528 free_irq(instance->irq, instance);
2529 instance->irq = 0;
2530 }
2531
2532 if (instance->circ_buf.buf) {
2533 PDEBUG("free circ_buf = %p size=%d",
2534 instance->circ_buf.buf,
2535 PAGE_SHIFT << ME6000_AO_CIRC_BUF_SIZE_ORDER);
2536 free_pages((unsigned long)instance->circ_buf.buf,
2537 ME6000_AO_CIRC_BUF_SIZE_ORDER);
2538 }
2539 instance->circ_buf.buf = NULL;
2540 }
2541
2542 me_subdevice_deinit(&instance->base);
2543 kfree(instance);
2544}
2545
2546me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
2547 spinlock_t * preload_reg_lock,
2548 uint32_t * preload_flags,
2549 uint32_t * triggering_flags,
2550 int ao_idx,
2551 int fifo,
2552 int irq,
2553 int high_range,
2554 struct workqueue_struct *me6000_wq)
2555{
2556 me6000_ao_subdevice_t *subdevice;
2557 int err;
2558
2559 PDEBUG("executed ID=%d.\n", ao_idx);
2560
2561 /* Allocate memory for subdevice instance */
2562 subdevice = kmalloc(sizeof(me6000_ao_subdevice_t), GFP_KERNEL);
2563
2564 if (!subdevice) {
2565 PERROR("Cannot get memory for subdevice instance.\n");
2566 return NULL;
2567 }
2568
2569 memset(subdevice, 0, sizeof(me6000_ao_subdevice_t));
2570
2571 /* Initialize subdevice base class */
2572 err = me_subdevice_init(&subdevice->base);
2573
2574 if (err) {
2575 PERROR("Cannot initialize subdevice base class instance.\n");
2576 kfree(subdevice);
2577 return NULL;
2578 }
2579 // Initialize spin locks.
2580 spin_lock_init(&subdevice->subdevice_lock);
2581
2582 subdevice->preload_reg_lock = preload_reg_lock;
2583 subdevice->preload_flags = preload_flags;
2584 subdevice->triggering_flags = triggering_flags;
2585
2586 /* Store analog output index */
2587 subdevice->ao_idx = ao_idx;
2588
2589 /* Store if analog output has fifo */
2590 subdevice->fifo = fifo;
2591
2592 if (subdevice->fifo & ME6000_AO_HAS_FIFO) {
2593 /* Allocate and initialize circular buffer */
2594 subdevice->circ_buf.mask = ME6000_AO_CIRC_BUF_COUNT - 1;
2595 subdevice->circ_buf.buf =
2596 (void *)__get_free_pages(GFP_KERNEL,
2597 ME6000_AO_CIRC_BUF_SIZE_ORDER);
2598 PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf,
2599 ME6000_AO_CIRC_BUF_SIZE);
2600
2601 if (!subdevice->circ_buf.buf) {
2602 PERROR
2603 ("Cannot initialize subdevice base class instance.\n");
2604 kfree(subdevice);
2605 return NULL;
2606 }
2607
2608 memset(subdevice->circ_buf.buf, 0, ME6000_AO_CIRC_BUF_SIZE);
2609 } else {
2610 subdevice->circ_buf.mask = 0;
2611 subdevice->circ_buf.buf = NULL;
2612 }
2613 subdevice->circ_buf.head = 0;
2614 subdevice->circ_buf.tail = 0;
2615
2616 subdevice->status = ao_status_none;
2617 subdevice->ao_control_task_flag = 0;
2618 subdevice->timeout.delay = 0;
2619 subdevice->timeout.start_time = jiffies;
2620
2621 /* Initialize wait queue */
2622 init_waitqueue_head(&subdevice->wait_queue);
2623
2624 /* Initialize single value to 0V */
2625 subdevice->single_value = 0x8000;
2626 subdevice->single_value_in_fifo = 0x8000;
2627
2628 /* Initialize range boarders */
2629 if (high_range) {
2630 subdevice->min = ME6000_AO_MIN_RANGE_HIGH;
2631 subdevice->max = ME6000_AO_MAX_RANGE_HIGH;
2632 } else {
2633 subdevice->min = ME6000_AO_MIN_RANGE;
2634 subdevice->max = ME6000_AO_MAX_RANGE;
2635 }
2636
2637 /* Register interrupt service routine */
2638
2639 if (subdevice->fifo & ME6000_AO_HAS_FIFO) {
2640 subdevice->irq = irq;
2641 if (request_irq(subdevice->irq, me6000_ao_isr,
2642#ifdef IRQF_DISABLED
2643 IRQF_DISABLED | IRQF_SHARED,
2644#else
2645 SA_INTERRUPT | SA_SHIRQ,
2646#endif
2647 ME6000_NAME, subdevice)) {
2648 PERROR("Cannot get interrupt line.\n");
2649 PDEBUG("free circ_buf = %p size=%d",
2650 subdevice->circ_buf.buf,
2651 PAGE_SHIFT << ME6000_AO_CIRC_BUF_SIZE_ORDER);
2652 free_pages((unsigned long)subdevice->circ_buf.buf,
2653 ME6000_AO_CIRC_BUF_SIZE_ORDER);
2654 subdevice->circ_buf.buf = NULL;
2655 kfree(subdevice);
2656 return NULL;
2657 }
2658 PINFO("Registered irq=%d.\n", subdevice->irq);
2659 } else {
2660 subdevice->irq = 0;
2661 }
2662
2663 /* Initialize registers */
2664 // Only streamed subdevices support interrupts. For the rest this register has no meaning.
2665 subdevice->irq_status_reg = reg_base + ME6000_AO_IRQ_STATUS_REG;
2666 subdevice->preload_reg = reg_base + ME6000_AO_PRELOAD_REG;
2667
2668 if (ao_idx == 0) {
2669 subdevice->ctrl_reg = reg_base + ME6000_AO_00_CTRL_REG;
2670 subdevice->status_reg = reg_base + ME6000_AO_00_STATUS_REG;
2671 subdevice->fifo_reg = reg_base + ME6000_AO_00_FIFO_REG;
2672 subdevice->timer_reg = reg_base + ME6000_AO_00_TIMER_REG;
2673 subdevice->irq_reset_reg =
2674 reg_base + ME6000_AO_00_IRQ_RESET_REG;
2675 subdevice->single_reg = reg_base + ME6000_AO_00_SINGLE_REG;
2676 } else if (ao_idx == 1) {
2677 subdevice->ctrl_reg = reg_base + ME6000_AO_01_CTRL_REG;
2678 subdevice->status_reg = reg_base + ME6000_AO_01_STATUS_REG;
2679 subdevice->fifo_reg = reg_base + ME6000_AO_01_FIFO_REG;
2680 subdevice->timer_reg = reg_base + ME6000_AO_01_TIMER_REG;
2681 subdevice->irq_reset_reg =
2682 reg_base + ME6000_AO_01_IRQ_RESET_REG;
2683 subdevice->single_reg = reg_base + ME6000_AO_01_SINGLE_REG;
2684 } else if (ao_idx == 2) {
2685 subdevice->ctrl_reg = reg_base + ME6000_AO_02_CTRL_REG;
2686 subdevice->status_reg = reg_base + ME6000_AO_02_STATUS_REG;
2687 subdevice->fifo_reg = reg_base + ME6000_AO_02_FIFO_REG;
2688 subdevice->timer_reg = reg_base + ME6000_AO_02_TIMER_REG;
2689 subdevice->irq_reset_reg =
2690 reg_base + ME6000_AO_02_IRQ_RESET_REG;
2691 subdevice->single_reg = reg_base + ME6000_AO_02_SINGLE_REG;
2692 } else if (ao_idx == 3) {
2693 subdevice->ctrl_reg = reg_base + ME6000_AO_03_CTRL_REG;
2694 subdevice->status_reg = reg_base + ME6000_AO_03_STATUS_REG;
2695 subdevice->fifo_reg = reg_base + ME6000_AO_03_FIFO_REG;
2696 subdevice->timer_reg = reg_base + ME6000_AO_03_TIMER_REG;
2697 subdevice->irq_reset_reg =
2698 reg_base + ME6000_AO_03_IRQ_RESET_REG;
2699 subdevice->single_reg = reg_base + ME6000_AO_03_SINGLE_REG;
2700 } else {
2701 subdevice->ctrl_reg = reg_base + ME6000_AO_DUMY;
2702 subdevice->fifo_reg = reg_base + ME6000_AO_DUMY;
2703 subdevice->timer_reg = reg_base + ME6000_AO_DUMY;
2704 subdevice->irq_reset_reg = reg_base + ME6000_AO_DUMY;
2705 subdevice->single_reg = reg_base + ME6000_AO_DUMY;
2706
2707 subdevice->status_reg = reg_base + ME6000_AO_SINGLE_STATUS_REG;
2708 if (ao_idx == 4) {
2709 subdevice->single_reg =
2710 reg_base + ME6000_AO_04_SINGLE_REG;
2711 } else if (ao_idx == 5) {
2712 subdevice->single_reg =
2713 reg_base + ME6000_AO_05_SINGLE_REG;
2714 } else if (ao_idx == 6) {
2715 subdevice->single_reg =
2716 reg_base + ME6000_AO_06_SINGLE_REG;
2717 } else if (ao_idx == 7) {
2718 subdevice->single_reg =
2719 reg_base + ME6000_AO_07_SINGLE_REG;
2720 } else if (ao_idx == 8) {
2721 subdevice->single_reg =
2722 reg_base + ME6000_AO_08_SINGLE_REG;
2723 } else if (ao_idx == 9) {
2724 subdevice->single_reg =
2725 reg_base + ME6000_AO_09_SINGLE_REG;
2726 } else if (ao_idx == 10) {
2727 subdevice->single_reg =
2728 reg_base + ME6000_AO_10_SINGLE_REG;
2729 } else if (ao_idx == 11) {
2730 subdevice->single_reg =
2731 reg_base + ME6000_AO_11_SINGLE_REG;
2732 } else if (ao_idx == 12) {
2733 subdevice->single_reg =
2734 reg_base + ME6000_AO_12_SINGLE_REG;
2735 } else if (ao_idx == 13) {
2736 subdevice->single_reg =
2737 reg_base + ME6000_AO_13_SINGLE_REG;
2738 } else if (ao_idx == 14) {
2739 subdevice->single_reg =
2740 reg_base + ME6000_AO_14_SINGLE_REG;
2741 } else if (ao_idx == 15) {
2742 subdevice->single_reg =
2743 reg_base + ME6000_AO_15_SINGLE_REG;
2744 } else {
2745 PERROR_CRITICAL("WRONG SUBDEVICE ID=%d!", ao_idx);
2746 me_subdevice_deinit((me_subdevice_t *) subdevice);
2747 if (subdevice->fifo) {
2748 free_pages((unsigned long)subdevice->circ_buf.
2749 buf, ME6000_AO_CIRC_BUF_SIZE_ORDER);
2750 }
2751 subdevice->circ_buf.buf = NULL;
2752 kfree(subdevice);
2753 return NULL;
2754 }
2755 }
2756#ifdef MEDEBUG_DEBUG_REG
2757 subdevice->reg_base = reg_base;
2758#endif
2759
2760 /* Override base class methods. */
2761 subdevice->base.me_subdevice_destructor = me6000_ao_destructor;
2762 subdevice->base.me_subdevice_io_reset_subdevice =
2763 me6000_ao_io_reset_subdevice;
2764 subdevice->base.me_subdevice_io_single_config =
2765 me6000_ao_io_single_config;
2766 subdevice->base.me_subdevice_io_single_read = me6000_ao_io_single_read;
2767 subdevice->base.me_subdevice_io_single_write =
2768 me6000_ao_io_single_write;
2769 subdevice->base.me_subdevice_io_stream_config =
2770 me6000_ao_io_stream_config;
2771 subdevice->base.me_subdevice_io_stream_new_values =
2772 me6000_ao_io_stream_new_values;
2773 subdevice->base.me_subdevice_io_stream_write =
2774 me6000_ao_io_stream_write;
2775 subdevice->base.me_subdevice_io_stream_start =
2776 me6000_ao_io_stream_start;
2777 subdevice->base.me_subdevice_io_stream_status =
2778 me6000_ao_io_stream_status;
2779 subdevice->base.me_subdevice_io_stream_stop = me6000_ao_io_stream_stop;
2780 subdevice->base.me_subdevice_query_number_channels =
2781 me6000_ao_query_number_channels;
2782 subdevice->base.me_subdevice_query_subdevice_type =
2783 me6000_ao_query_subdevice_type;
2784 subdevice->base.me_subdevice_query_subdevice_caps =
2785 me6000_ao_query_subdevice_caps;
2786 subdevice->base.me_subdevice_query_subdevice_caps_args =
2787 me6000_ao_query_subdevice_caps_args;
2788 subdevice->base.me_subdevice_query_range_by_min_max =
2789 me6000_ao_query_range_by_min_max;
2790 subdevice->base.me_subdevice_query_number_ranges =
2791 me6000_ao_query_number_ranges;
2792 subdevice->base.me_subdevice_query_range_info =
2793 me6000_ao_query_range_info;
2794 subdevice->base.me_subdevice_query_timer = me6000_ao_query_timer;
2795
2796 //prepare work queue and work function
2797 subdevice->me6000_workqueue = me6000_wq;
2798
2799/* workqueue API changed in kernel 2.6.20 */
2800#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
2801 INIT_WORK(&subdevice->ao_control_task, me6000_ao_work_control_task,
2802 (void *)subdevice);
2803#else
2804 INIT_DELAYED_WORK(&subdevice->ao_control_task,
2805 me6000_ao_work_control_task);
2806#endif
2807
2808 if (subdevice->fifo) { //Set speed
2809 outl(ME6000_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
2810 subdevice->hardware_stop_delay = HZ / 10; //100ms
2811 }
2812
2813 return subdevice;
2814}
2815
2816/** @brief Stop presentation. Preserve FIFOs.
2817*
2818* @param instance The subdevice instance (pointer).
2819*/
2820int inline ao_stop_immediately(me6000_ao_subdevice_t * instance)
2821{
2822 unsigned long cpu_flags;
2823 uint32_t ctrl;
2824 int timeout;
2825 int i;
2826 uint32_t single_mask;
2827
2828 single_mask =
2829 (instance->ao_idx - ME6000_AO_SINGLE_STATUS_OFFSET <
2830 0) ? 0x0000 : (0x0001 << (instance->ao_idx -
2831 ME6000_AO_SINGLE_STATUS_OFFSET));
2832
2833 timeout =
2834 (instance->hardware_stop_delay >
2835 (HZ / 10)) ? instance->hardware_stop_delay : HZ / 10;
2836 for (i = 0; i <= timeout; i++) {
2837 if (instance->fifo) {
2838 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
2839 // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
2840 ctrl = inl(instance->ctrl_reg);
2841 ctrl |=
2842 ME6000_AO_CTRL_BIT_STOP |
2843 ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
2844 ctrl &=
2845 ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
2846 ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
2847 outl(ctrl, instance->ctrl_reg);
2848 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
2849 instance->reg_base,
2850 instance->ctrl_reg - instance->reg_base,
2851 ctrl);
2852 spin_unlock_irqrestore(&instance->subdevice_lock,
2853 cpu_flags);
2854
2855 if (!(inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM)) { // Exit.
2856 break;
2857 }
2858 } else {
2859 if (!(inl(instance->status_reg) & single_mask)) { // Exit.
2860 break;
2861 }
2862 }
2863
2864 PINFO("<%s> Wait for stop: %d\n", __FUNCTION__, i);
2865
2866 //Still working!
2867 set_current_state(TASK_INTERRUPTIBLE);
2868 schedule_timeout(1);
2869 }
2870
2871 if (i > timeout) {
2872 PERROR_CRITICAL("FSM IS BUSY!\n");
2873 return ME_ERRNO_INTERNAL;
2874 }
2875 return ME_ERRNO_SUCCESS;
2876}
2877
2878/** @brief Copy data from circular buffer to fifo (fast) in wraparound.
2879* @note This is time critical function. Checking is done at begining and end only.
2880* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
2881*
2882* @param instance The subdevice instance (pointer).
2883* @param count Maximum number of copied data.
2884* @param start_pos Position of the firs value in buffer.
2885*
2886* @return On success: Number of copied data.
2887* @return On error/success: 0. No datas were copied => no data in buffer.
2888* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
2889*/
2890int inline ao_write_data_wraparound(me6000_ao_subdevice_t * instance, int count,
2891 int start_pos)
2892{ /// @note This is time critical function!
2893 uint32_t status;
2894 uint32_t value;
2895 int pos =
2896 (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
2897 int local_count = count;
2898 int i = 1;
2899
2900 if (count <= 0) { //Wrong count!
2901 return 0;
2902 }
2903
2904 while (i < local_count) {
2905 //Get value from buffer
2906 value = *(instance->circ_buf.buf + pos);
2907 //Prepare it
2908 if (instance->ao_idx & 0x1) {
2909 value <<= 16;
2910 }
2911 //Put value to FIFO
2912 outl(value, instance->fifo_reg);
2913 //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
2914
2915 pos++;
2916 pos &= instance->circ_buf.mask;
2917 if (pos == instance->circ_buf.head) {
2918 pos = instance->circ_buf.tail;
2919 }
2920 i++;
2921 }
2922
2923 status = inl(instance->status_reg);
2924 if (!(status & ME6000_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied!
2925 PERROR("idx=%d FIFO is full before all datas were copied!\n",
2926 instance->ao_idx);
2927 return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
2928 } else { //Add last value
2929 value = *(instance->circ_buf.buf + pos);
2930 if (instance->ao_idx & 0x1) {
2931 value <<= 16;
2932 }
2933 //Put value to FIFO
2934 outl(value, instance->fifo_reg);
2935 //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
2936 }
2937
2938 PINFO("idx=%d WRAPAROUND LOADED %d values\n", instance->ao_idx,
2939 local_count);
2940 return local_count;
2941}
2942
2943/** @brief Copy data from software buffer to fifo (fast).
2944* @note This is time critical function. Checking is done at begining and end only.
2945* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
2946*
2947* @param instance The subdevice instance (pointer).
2948* @param count Maximum number of copied data.
2949* @param start_pos Position of the firs value in buffer.
2950*
2951* @return On success: Number of copied data.
2952* @return On error/success: 0. No datas were copied => no data in buffer.
2953* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
2954*/
2955int inline ao_write_data(me6000_ao_subdevice_t * instance, int count,
2956 int start_pos)
2957{ /// @note This is time critical function!
2958 uint32_t status;
2959 uint32_t value;
2960 int pos =
2961 (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
2962 int local_count = count;
2963 int max_count;
2964 int i = 1;
2965
2966 if (count <= 0) { //Wrong count!
2967 return 0;
2968 }
2969
2970 max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
2971 if (max_count <= 0) { //No data to copy!
2972 return 0;
2973 }
2974
2975 if (max_count < count) {
2976 local_count = max_count;
2977 }
2978
2979 while (i < local_count) {
2980 //Get value from buffer
2981 value = *(instance->circ_buf.buf + pos);
2982 //Prepare it
2983 if (instance->ao_idx & 0x1) {
2984 value <<= 16;
2985 }
2986 //Put value to FIFO
2987 outl(value, instance->fifo_reg);
2988 //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
2989
2990 pos++;
2991 pos &= instance->circ_buf.mask;
2992 i++;
2993 }
2994
2995 status = inl(instance->status_reg);
2996 if (!(status & ME6000_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied!
2997 PERROR("idx=%d FIFO is full before all datas were copied!\n",
2998 instance->ao_idx);
2999 return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
3000 } else { //Add last value
3001 value = *(instance->circ_buf.buf + pos);
3002 if (instance->ao_idx & 0x1) {
3003 value <<= 16;
3004 }
3005 //Put value to FIFO
3006 outl(value, instance->fifo_reg);
3007 //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
3008 }
3009
3010 PINFO("idx=%d FAST LOADED %d values\n", instance->ao_idx, local_count);
3011 return local_count;
3012}
3013
3014/** @brief Copy data from software buffer to fifo (slow).
3015* @note This is slow function that copy all data from buffer to FIFO with full control.
3016*
3017* @param instance The subdevice instance (pointer).
3018* @param count Maximum number of copied data.
3019* @param start_pos Position of the firs value in buffer.
3020*
3021* @return On success: Number of copied values.
3022* @return On error/success: 0. FIFO was full at begining.
3023* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
3024*/
3025int inline ao_write_data_pooling(me6000_ao_subdevice_t * instance, int count,
3026 int start_pos)
3027{ /// @note This is slow function!
3028 uint32_t status;
3029 uint32_t value;
3030 int pos =
3031 (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
3032 int local_count = count;
3033 int i;
3034 int max_count;
3035
3036 if (count <= 0) { //Wrong count!
3037 PERROR("idx=%d SLOW LOADED: Wrong count!\n", instance->ao_idx);
3038 return 0;
3039 }
3040
3041 max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
3042 if (max_count <= 0) { //No data to copy!
3043 PERROR("idx=%d SLOW LOADED: No data to copy!\n",
3044 instance->ao_idx);
3045 return 0;
3046 }
3047
3048 if (max_count < count) {
3049 local_count = max_count;
3050 }
3051
3052 for (i = 0; i < local_count; i++) {
3053 status = inl(instance->status_reg);
3054 if (!(status & ME6000_AO_STATUS_BIT_FF)) { //FIFO is full!
3055 return i;
3056 }
3057 //Get value from buffer
3058 value = *(instance->circ_buf.buf + pos);
3059 //Prepare it
3060 if (instance->ao_idx & 0x1) {
3061 value <<= 16;
3062 }
3063 //Put value to FIFO
3064 outl(value, instance->fifo_reg);
3065 //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
3066
3067 pos++;
3068 pos &= instance->circ_buf.mask;
3069 }
3070
3071 PINFO("idx=%d SLOW LOADED %d values\n", instance->ao_idx, local_count);
3072 return local_count;
3073}
3074
3075/** @brief Copy data from user space to circular buffer.
3076* @param instance The subdevice instance (pointer).
3077* @param count Number of datas in user space.
3078* @param user_values Buffer's pointer.
3079*
3080* @return On success: Number of copied values.
3081* @return On error: -ME_ERRNO_INTERNAL.
3082*/
3083int inline ao_get_data_from_user(me6000_ao_subdevice_t * instance, int count,
3084 int *user_values)
3085{
3086 int i, err;
3087 int empty_space;
3088 int copied;
3089 int value;
3090
3091 empty_space = me_circ_buf_space(&instance->circ_buf);
3092 //We have only this space free.
3093 copied = (count < empty_space) ? count : empty_space;
3094 for (i = 0; i < copied; i++) { //Copy from user to buffer
3095 if ((err = get_user(value, (int *)(user_values + i)))) {
3096 PERROR
3097 ("idx=%d BUFFER LOADED: get_user(0x%p) return an error: %d\n",
3098 instance->ao_idx, user_values + i, err);
3099 return -ME_ERRNO_INTERNAL;
3100 }
3101 /// @note The analog output in me6000 series has size of 16 bits.
3102 *(instance->circ_buf.buf + instance->circ_buf.head) =
3103 (uint16_t) value;
3104 instance->circ_buf.head++;
3105 instance->circ_buf.head &= instance->circ_buf.mask;
3106 }
3107
3108 PINFO("idx=%d BUFFER LOADED %d values\n", instance->ao_idx, copied);
3109 return copied;
3110}
3111
3112static void me6000_ao_work_control_task(
3113#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
3114 void *subdevice
3115#else
3116 struct work_struct *work
3117#endif
3118 )
3119{
3120 me6000_ao_subdevice_t *instance;
3121 unsigned long cpu_flags = 0;
3122 uint32_t status;
3123 uint32_t ctrl;
3124 uint32_t synch;
3125 int reschedule = 0;
3126 int signaling = 0;
3127 uint32_t single_mask;
3128
3129#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
3130 instance = (me6000_ao_subdevice_t *) subdevice;
3131#else
3132 instance =
3133 container_of((void *)work, me6000_ao_subdevice_t, ao_control_task);
3134#endif
3135 PINFO("<%s: %ld> executed. idx=%d\n", __FUNCTION__, jiffies,
3136 instance->ao_idx);
3137
3138 status = inl(instance->status_reg);
3139 PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
3140 instance->status_reg - instance->reg_base, status);
3141
3142/// @note AO_STATUS_BIT_FSM doesn't work as should be for pure single channels (idx>=4)
3143// single_mask = (instance->ao_idx-ME6000_AO_SINGLE_STATUS_OFFSET < 0) ? 0x0000 : (0x0001 << (instance->ao_idx-ME6000_AO_SINGLE_STATUS_OFFSET));
3144 single_mask = *instance->triggering_flags & (0x1 << instance->ao_idx);
3145
3146 switch (instance->status) { // Checking actual mode.
3147
3148 // Not configured for work.
3149 case ao_status_none:
3150 break;
3151
3152 //This are stable modes. No need to do anything. (?)
3153 case ao_status_single_configured:
3154 case ao_status_stream_configured:
3155 case ao_status_stream_fifo_error:
3156 case ao_status_stream_buffer_error:
3157 case ao_status_stream_error:
3158 PERROR("Shouldn't be running!.\n");
3159 break;
3160
3161 // Single modes
3162 case ao_status_single_run_wait:
3163 case ao_status_single_run:
3164 case ao_status_single_end_wait:
3165 if (instance->fifo) { // Extra registers.
3166 if (!(status & ME6000_AO_STATUS_BIT_FSM)) { // State machine is not working.
3167 if (((instance->fifo & ME6000_AO_HAS_FIFO)
3168 && (!(status & ME6000_AO_STATUS_BIT_EF)))
3169 || (!(instance->fifo & ME6000_AO_HAS_FIFO))) { // Single is in end state.
3170 PDEBUG
3171 ("Single call has been complited.\n");
3172
3173 // Set correct value for single_read();
3174 instance->single_value =
3175 instance->single_value_in_fifo;
3176
3177 // Set status as 'ao_status_single_end'
3178 instance->status = ao_status_single_end;
3179
3180 spin_lock(instance->preload_reg_lock);
3181 if ((single_mask) && (*instance->preload_flags & (ME6000_AO_SYNC_HOLD << instance->ao_idx))) { // This is one of synchronous start channels. Set all as triggered.
3182 *instance->triggering_flags =
3183 0x00000000;
3184 } else {
3185 //Set this channel as triggered (none active).
3186 *instance->triggering_flags &=
3187 ~(0x1 << instance->ao_idx);
3188 }
3189 spin_unlock(instance->preload_reg_lock);
3190
3191 // Signal the end.
3192 signaling = 1;
3193 // Wait for stop ISM.
3194 reschedule = 1;
3195
3196 break;
3197 }
3198 }
3199 // Check timeout.
3200 if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
3201 PDEBUG("Timeout reached.\n");
3202 // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
3203 spin_lock_irqsave(&instance->subdevice_lock,
3204 cpu_flags);
3205 ctrl = inl(instance->ctrl_reg);
3206 ctrl |=
3207 ME6000_AO_CTRL_BIT_STOP |
3208 ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
3209 ctrl &=
3210 ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
3211 ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
3212 ctrl &=
3213 ~(ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
3214 ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
3215 //Disabling FIFO
3216 ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_FIFO;
3217
3218 outl(ctrl, instance->ctrl_reg);
3219 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3220 instance->reg_base,
3221 instance->ctrl_reg -
3222 instance->reg_base, ctrl);
3223 spin_unlock_irqrestore(&instance->
3224 subdevice_lock,
3225 cpu_flags);
3226
3227 //Reset interrupt latch
3228 inl(instance->irq_reset_reg);
3229
3230 spin_lock(instance->preload_reg_lock);
3231 //Remove from synchronous start. Block triggering from this output.
3232 synch = inl(instance->preload_reg);
3233 synch &=
3234 ~((ME6000_AO_SYNC_HOLD |
3235 ME6000_AO_SYNC_EXT_TRIG) << instance->
3236 ao_idx);
3237 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO - set to single safe mode
3238 synch |=
3239 ME6000_AO_SYNC_HOLD << instance->
3240 ao_idx;
3241 }
3242 outl(synch, instance->preload_reg);
3243 PDEBUG_REG
3244 ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
3245 instance->reg_base,
3246 instance->preload_reg - instance->reg_base,
3247 synch);
3248 //Set this channel as triggered (none active).
3249 *instance->triggering_flags &=
3250 ~(0x1 << instance->ao_idx);
3251 spin_unlock(instance->preload_reg_lock);
3252
3253 // Set correct value for single_read();
3254 instance->single_value_in_fifo =
3255 instance->single_value;
3256
3257 instance->status = ao_status_single_end;
3258
3259 // Signal the end.
3260 signaling = 1;
3261 }
3262 } else { // No extra registers.
3263/*
3264 if (!(status & single_mask))
3265 {// State machine is not working.
3266 PDEBUG("Single call has been complited.\n");
3267
3268 // Set correct value for single_read();
3269 instance->single_value = instance->single_value_in_fifo;
3270
3271 // Set status as 'ao_status_single_end'
3272 instance->status = ao_status_single_end;
3273
3274 // Signal the end.
3275 signaling = 1;
3276 // Wait for stop ISM.
3277 reschedule = 1;
3278
3279 break;
3280 }
3281*/
3282 if (!single_mask) { // Was triggered.
3283 PDEBUG("Single call has been complited.\n");
3284
3285 // Set correct value for single_read();
3286 instance->single_value =
3287 instance->single_value_in_fifo;
3288
3289 // Set status as 'ao_status_single_end'
3290 instance->status = ao_status_single_end;
3291
3292 // Signal the end.
3293 signaling = 1;
3294
3295 break;
3296 }
3297 // Check timeout.
3298 if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
3299 PDEBUG("Timeout reached.\n");
3300
3301 spin_lock(instance->preload_reg_lock);
3302 //Remove from synchronous start. Block triggering from this output.
3303 synch = inl(instance->preload_reg);
3304 synch &=
3305 ~(ME6000_AO_SYNC_EXT_TRIG << instance->
3306 ao_idx);
3307 synch |=
3308 ME6000_AO_SYNC_HOLD << instance->ao_idx;
3309
3310 outl(synch, instance->preload_reg);
3311 PDEBUG_REG
3312 ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
3313 instance->reg_base,
3314 instance->preload_reg - instance->reg_base,
3315 synch);
3316 //Set this channel as triggered (none active).
3317 *instance->triggering_flags &=
3318 ~(0x1 << instance->ao_idx);
3319 spin_unlock(instance->preload_reg_lock);
3320
3321 // Restore old settings.
3322 PDEBUG("Write old value back to register.\n");
3323 outl(instance->single_value,
3324 instance->single_reg);
3325 PDEBUG_REG
3326 ("single_reg outl(0x%lX+0x%lX)=0x%x\n",
3327 instance->reg_base,
3328 instance->single_reg - instance->reg_base,
3329 instance->single_value);
3330
3331 // Set correct value for single_read();
3332 instance->single_value_in_fifo =
3333 instance->single_value;
3334
3335 instance->status = ao_status_single_end;
3336
3337 // Signal the end.
3338 signaling = 1;
3339 }
3340 }
3341
3342 // Wait for stop.
3343 reschedule = 1;
3344 break;
3345
3346 case ao_status_stream_end:
3347 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO
3348 PERROR_CRITICAL
3349 ("Streaming on single device! This feature is not implemented in this version!\n");
3350 instance->status = ao_status_stream_error;
3351 // Signal the end.
3352 signaling = 1;
3353 break;
3354 }
3355 case ao_status_single_end:
3356 if (instance->fifo) { // Extra registers.
3357 if (status & ME6000_AO_STATUS_BIT_FSM) { // State machine is working but the status is set to end. Force stop.
3358
3359 // Wait for stop.
3360 reschedule = 1;
3361 }
3362
3363 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
3364 // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
3365 ctrl = inl(instance->ctrl_reg);
3366 ctrl |=
3367 ME6000_AO_CTRL_BIT_IMMEDIATE_STOP |
3368 ME6000_AO_CTRL_BIT_STOP;
3369 ctrl &=
3370 ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
3371 ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
3372 outl(ctrl, instance->ctrl_reg);
3373 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3374 instance->reg_base,
3375 instance->ctrl_reg - instance->reg_base,
3376 ctrl);
3377 spin_unlock_irqrestore(&instance->subdevice_lock,
3378 cpu_flags);
3379
3380 //Reset interrupt latch
3381 inl(instance->irq_reset_reg);
3382 } else { // No extra registers.
3383/*
3384 if (status & single_mask)
3385 {// State machine is working but the status is set to end. Force stop.
3386
3387 // Wait for stop.
3388 reschedule = 1;
3389 }
3390*/
3391 }
3392 break;
3393
3394 // Stream modes
3395 case ao_status_stream_run_wait:
3396 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO
3397 PERROR_CRITICAL
3398 ("Streaming on single device! This feature is not implemented in this version!\n");
3399 instance->status = ao_status_stream_error;
3400 // Signal the end.
3401 signaling = 1;
3402 break;
3403 }
3404
3405 if (status & ME6000_AO_STATUS_BIT_FSM) { // State machine is working. Waiting for start finish.
3406 instance->status = ao_status_stream_run;
3407
3408 // Signal end of this step
3409 signaling = 1;
3410 } else { // State machine is not working.
3411 if (!(status & ME6000_AO_STATUS_BIT_EF)) { // FIFO is empty. Procedure has started and finish already!
3412 instance->status = ao_status_stream_end;
3413
3414 // Signal the end.
3415 signaling = 1;
3416 // Wait for stop.
3417 reschedule = 1;
3418 break;
3419 }
3420 }
3421
3422 // Check timeout.
3423 if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
3424 PDEBUG("Timeout reached.\n");
3425 // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
3426 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
3427 ctrl = inl(instance->ctrl_reg);
3428 ctrl |=
3429 ME6000_AO_CTRL_BIT_STOP |
3430 ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
3431 ctrl &=
3432 ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
3433 ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
3434 outl(ctrl, instance->ctrl_reg);
3435 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
3436 instance->reg_base,
3437 instance->ctrl_reg - instance->reg_base,
3438 ctrl);
3439 spin_unlock_irqrestore(&instance->subdevice_lock,
3440 cpu_flags);
3441
3442 //Reset interrupt latch
3443 inl(instance->irq_reset_reg);
3444
3445 spin_lock(instance->preload_reg_lock);
3446 //Remove from synchronous start. Block triggering from this output.
3447 synch = inl(instance->preload_reg);
3448 synch &=
3449 ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
3450 instance->ao_idx);
3451 outl(synch, instance->preload_reg);
3452 PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
3453 instance->reg_base,
3454 instance->preload_reg - instance->reg_base,
3455 synch);
3456 spin_unlock(instance->preload_reg_lock);
3457
3458 instance->status = ao_status_stream_end;
3459
3460 // Signal the end.
3461 signaling = 1;
3462 }
3463 // Wait for stop.
3464 reschedule = 1;
3465 break;
3466
3467 case ao_status_stream_run:
3468 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO
3469 PERROR_CRITICAL
3470 ("Streaming on single device! This feature is not implemented in this version!\n");
3471 instance->status = ao_status_stream_error;
3472 // Signal the end.
3473 signaling = 1;
3474 break;
3475 }
3476
3477 if (!(status & ME6000_AO_STATUS_BIT_FSM)) { // State machine is not working. This is an error.
3478 // BROKEN PIPE!
3479 if (!(status & ME6000_AO_STATUS_BIT_EF)) { // FIFO is empty.
3480 if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty.
3481 if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. Requed data shown.
3482 PDEBUG
3483 ("ISM stoped. No data in FIFO. Buffer is not empty.\n");
3484 instance->status =
3485 ao_status_stream_end;
3486 } else {
3487 PERROR
3488 ("Output stream has been broken. ISM stoped. No data in FIFO. Buffer is not empty.\n");
3489 instance->status =
3490 ao_status_stream_buffer_error;
3491 }
3492 } else { // Software buffer is empty.
3493 PDEBUG
3494 ("ISM stoped. No data in FIFO. Buffer is empty.\n");
3495 instance->status = ao_status_stream_end;
3496 }
3497 } else { // There are still datas in FIFO.
3498 if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty.
3499 PERROR
3500 ("Output stream has been broken. ISM stoped but some data in FIFO and buffer.\n");
3501 } else { // Software buffer is empty.
3502 PERROR
3503 ("Output stream has been broken. ISM stoped but some data in FIFO. Buffer is empty.\n");
3504 }
3505 instance->status = ao_status_stream_fifo_error;
3506
3507 }
3508
3509 // Signal the failure.
3510 signaling = 1;
3511 break;
3512 }
3513 // Wait for stop.
3514 reschedule = 1;
3515 break;
3516
3517 case ao_status_stream_end_wait:
3518 if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO
3519 PERROR_CRITICAL
3520 ("Streaming on single device! This feature is not implemented in this version!\n");
3521 instance->status = ao_status_stream_error;
3522 // Signal the end.
3523 signaling = 1;
3524 break;
3525 }
3526
3527 if (!(status & ME6000_AO_STATUS_BIT_FSM)) { // State machine is not working. Waiting for stop finish.
3528 instance->status = ao_status_stream_end;
3529 signaling = 1;
3530 }
3531 // State machine is working.
3532 reschedule = 1;
3533 break;
3534
3535 default:
3536 PERROR_CRITICAL("Status is in wrong state (%d)!\n",
3537 instance->status);
3538 instance->status = ao_status_stream_error;
3539 // Signal the end.
3540 signaling = 1;
3541 break;
3542
3543 }
3544
3545 if (signaling) { //Signal it.
3546 wake_up_interruptible_all(&instance->wait_queue);
3547 }
3548
3549 if (instance->ao_control_task_flag && reschedule) { // Reschedule task
3550 queue_delayed_work(instance->me6000_workqueue,
3551 &instance->ao_control_task, 1);
3552 } else {
3553 PINFO("<%s> Ending control task.\n", __FUNCTION__);
3554 }
3555
3556}
3557
3558static int me6000_ao_query_range_by_min_max(me_subdevice_t * subdevice,
3559 int unit,
3560 int *min,
3561 int *max, int *maxdata, int *range)
3562{
3563 me6000_ao_subdevice_t *instance;
3564
3565 instance = (me6000_ao_subdevice_t *) subdevice;
3566
3567 PDEBUG("executed. idx=%d\n", instance->ao_idx);
3568
3569 if ((*max - *min) < 0) {
3570 PERROR("Invalid minimum and maximum values specified.\n");
3571 return ME_ERRNO_INVALID_MIN_MAX;
3572 }
3573
3574 if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
3575 if ((*max <= (instance->max + 1000)) && (*min >= instance->min)) {
3576 *min = instance->min;
3577 *max = instance->max;
3578 *maxdata = ME6000_AO_MAX_DATA;
3579 *range = 0;
3580 } else {
3581 PERROR("No matching range available.\n");
3582 return ME_ERRNO_NO_RANGE;
3583 }
3584 } else {
3585 PERROR("Invalid physical unit specified.\n");
3586 return ME_ERRNO_INVALID_UNIT;
3587 }
3588
3589 return ME_ERRNO_SUCCESS;
3590}
3591
3592static int me6000_ao_query_number_ranges(me_subdevice_t * subdevice,
3593 int unit, int *count)
3594{
3595 me6000_ao_subdevice_t *instance;
3596
3597 instance = (me6000_ao_subdevice_t *) subdevice;
3598
3599 PDEBUG("executed. idx=%d\n", instance->ao_idx);
3600
3601 if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
3602 *count = 1;
3603 } else {
3604 *count = 0;
3605 }
3606
3607 return ME_ERRNO_SUCCESS;
3608}
3609
3610static int me6000_ao_query_range_info(me_subdevice_t * subdevice,
3611 int range,
3612 int *unit,
3613 int *min, int *max, int *maxdata)
3614{
3615 me6000_ao_subdevice_t *instance;
3616
3617 instance = (me6000_ao_subdevice_t *) subdevice;
3618
3619 PDEBUG("executed. idx=%d\n", instance->ao_idx);
3620
3621 if (range == 0) {
3622 *unit = ME_UNIT_VOLT;
3623 *min = instance->min;
3624 *max = instance->max;
3625 *maxdata = ME6000_AO_MAX_DATA;
3626 } else {
3627 PERROR("Invalid range number specified.\n");
3628 return ME_ERRNO_INVALID_RANGE;
3629 }
3630
3631 return ME_ERRNO_SUCCESS;
3632}
3633
3634static int me6000_ao_query_timer(me_subdevice_t * subdevice,
3635 int timer,
3636 int *base_frequency,
3637 long long *min_ticks, long long *max_ticks)
3638{
3639 me6000_ao_subdevice_t *instance;
3640
3641 instance = (me6000_ao_subdevice_t *) subdevice;
3642
3643 PDEBUG("executed. idx=%d\n", instance->ao_idx);
3644
3645 if (instance->fifo) { //Streaming device.
3646 *base_frequency = ME6000_AO_BASE_FREQUENCY;
3647 if (timer == ME_TIMER_ACQ_START) {
3648 *min_ticks = ME6000_AO_MIN_ACQ_TICKS;
3649 *max_ticks = ME6000_AO_MAX_ACQ_TICKS;
3650 } else if (timer == ME_TIMER_CONV_START) {
3651 *min_ticks = ME6000_AO_MIN_CHAN_TICKS;
3652 *max_ticks = ME6000_AO_MAX_CHAN_TICKS;
3653 }
3654 } else { //Not streaming device!
3655 *base_frequency = 0;
3656 *min_ticks = 0;
3657 *max_ticks = 0;
3658 }
3659
3660 return ME_ERRNO_SUCCESS;
3661}
3662
3663static int me6000_ao_query_number_channels(me_subdevice_t * subdevice,
3664 int *number)
3665{
3666 me6000_ao_subdevice_t *instance;
3667 instance = (me6000_ao_subdevice_t *) subdevice;
3668
3669 PDEBUG("executed. idx=%d\n", instance->ao_idx);
3670
3671 *number = 1;
3672 return ME_ERRNO_SUCCESS;
3673}
3674
3675static int me6000_ao_query_subdevice_type(me_subdevice_t * subdevice,
3676 int *type, int *subtype)
3677{
3678 me6000_ao_subdevice_t *instance;
3679
3680 instance = (me6000_ao_subdevice_t *) subdevice;
3681
3682 PDEBUG("executed. idx=%d\n", instance->ao_idx);
3683
3684 *type = ME_TYPE_AO;
3685 *subtype =
3686 (instance->
3687 fifo & ME6000_AO_HAS_FIFO) ? ME_SUBTYPE_STREAMING :
3688 ME_SUBTYPE_SINGLE;
3689
3690 return ME_ERRNO_SUCCESS;
3691}
3692
3693static int me6000_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
3694{
3695 me6000_ao_subdevice_t *instance;
3696 instance = (me6000_ao_subdevice_t *) subdevice;
3697
3698 PDEBUG("executed. idx=%d\n", instance->ao_idx);
3699
3700 *caps =
3701 ME_CAPS_AO_TRIG_SYNCHRONOUS | ((instance->fifo) ? ME_CAPS_AO_FIFO :
3702 ME_CAPS_NONE);
3703
3704 return ME_ERRNO_SUCCESS;
3705}
3706
3707static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
3708 int cap, int *args, int count)
3709{
3710 me6000_ao_subdevice_t *instance;
3711 int err = ME_ERRNO_SUCCESS;
3712
3713 instance = (me6000_ao_subdevice_t *) subdevice;
3714
3715 PDEBUG("executed. idx=%d\n", instance->ao_idx);
3716
3717 if (count != 1) {
3718 PERROR("Invalid capability argument count.\n");
3719 return ME_ERRNO_INVALID_CAP_ARG_COUNT;
3720 }
3721
3722 switch (cap) {
3723 case ME_CAP_AI_FIFO_SIZE:
3724 args[0] = (instance->fifo) ? ME6000_AO_FIFO_COUNT : 0;
3725 break;
3726
3727 case ME_CAP_AI_BUFFER_SIZE:
3728 args[0] =
3729 (instance->circ_buf.buf) ? ME6000_AO_CIRC_BUF_COUNT : 0;
3730 break;
3731
3732 default:
3733 PERROR("Invalid capability.\n");
3734 err = ME_ERRNO_INVALID_CAP;
3735 args[0] = 0;
3736 }
3737
3738 return err;
3739}
diff --git a/drivers/staging/meilhaus/me6000_ao.h b/drivers/staging/meilhaus/me6000_ao.h
new file mode 100644
index 000000000000..9629649cd410
--- /dev/null
+++ b/drivers/staging/meilhaus/me6000_ao.h
@@ -0,0 +1,200 @@
1/**
2 * @file me6000_ao.h
3 *
4 * @brief Meilhaus ME-6000 analog output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME6000_AO_H_
28#define _ME6000_AO_H_
29
30#include <linux/version.h>
31#include "mesubdevice.h"
32#include "mecirc_buf.h"
33#include "meioctl.h"
34
35#ifdef __KERNEL__
36
37#define ME6000_AO_MAX_SUBDEVICES 16
38#define ME6000_AO_FIFO_COUNT 8192
39
40#define ME6000_AO_BASE_FREQUENCY 33000000L
41
42#define ME6000_AO_MIN_ACQ_TICKS 0LL
43#define ME6000_AO_MAX_ACQ_TICKS 0LL
44
45#define ME6000_AO_MIN_CHAN_TICKS 66LL
46#define ME6000_AO_MAX_CHAN_TICKS 0xFFFFFFFFLL
47
48#define ME6000_AO_MIN_RANGE -10000000
49#define ME6000_AO_MAX_RANGE 9999694
50
51#define ME6000_AO_MIN_RANGE_HIGH 0
52#define ME6000_AO_MAX_RANGE_HIGH 49999237
53
54#define ME6000_AO_MAX_DATA 0xFFFF
55
56#ifdef ME_SYNAPSE
57# define ME6000_AO_CIRC_BUF_SIZE_ORDER 8 // 2^n PAGES =>> Maximum value of 1MB for Synapse
58#else
59# define ME6000_AO_CIRC_BUF_SIZE_ORDER 5 // 2^n PAGES =>> 128KB
60#endif
61#define ME6000_AO_CIRC_BUF_SIZE PAGE_SIZE<<ME6000_AO_CIRC_BUF_SIZE_ORDER // Buffer size in bytes.
62
63# ifdef _CBUFF_32b_t
64# define ME6000_AO_CIRC_BUF_COUNT ((ME6000_AO_CIRC_BUF_SIZE) / sizeof(uint32_t)) // Size in values
65# else
66# define ME6000_AO_CIRC_BUF_COUNT ((ME6000_AO_CIRC_BUF_SIZE) / sizeof(uint16_t)) // Size in values
67# endif
68
69# define ME6000_AO_CONTINOUS 0x0
70# define ME6000_AO_WRAP_MODE 0x1
71# define ME6000_AO_HW_MODE 0x2
72
73# define ME6000_AO_HW_WRAP_MODE (ME6000_AO_WRAP_MODE | ME6000_AO_HW_MODE)
74# define ME6000_AO_SW_WRAP_MODE ME6000_AO_WRAP_MODE
75
76# define ME6000_AO_INF_STOP_MODE 0x0
77# define ME6000_AO_ACQ_STOP_MODE 0x1
78# define ME6000_AO_SCAN_STOP_MODE 0x2
79
80# define ME6000_AO_EXTRA_HARDWARE 0x1
81# define ME6000_AO_HAS_FIFO 0x2
82
83typedef enum ME6000_AO_STATUS {
84 ao_status_none = 0,
85 ao_status_single_configured,
86 ao_status_single_run_wait,
87 ao_status_single_run,
88 ao_status_single_end_wait,
89 ao_status_single_end,
90 ao_status_stream_configured,
91 ao_status_stream_run_wait,
92 ao_status_stream_run,
93 ao_status_stream_end_wait,
94 ao_status_stream_end,
95 ao_status_stream_fifo_error,
96 ao_status_stream_buffer_error,
97 ao_status_stream_error,
98 ao_status_last
99} ME6000_AO_STATUS;
100
101typedef struct me6000_ao_timeout {
102 unsigned long start_time;
103 unsigned long delay;
104} me6000_ao_timeout_t;
105
106/**
107 * @brief The ME-6000 analog output subdevice class.
108 */
109typedef struct me6000_ao_subdevice {
110 /* Inheritance */
111 me_subdevice_t base; /**< The subdevice base class. */
112 unsigned int ao_idx;
113
114 /* Attributes */
115 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
116 spinlock_t *preload_reg_lock; /**< Spin lock to protect preload_reg from concurrent access. */
117
118 uint32_t *preload_flags;
119 uint32_t *triggering_flags;
120
121 /* Hardware feautres */
122 unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */
123 int fifo; /**< If set this device has a FIFO. */
124
125 //Range
126 int min;
127 int max;
128
129 int single_value; /**< Mirror of the output value in single mode. */
130 int single_value_in_fifo; /**< Mirror of the value written in single mode. */
131 uint32_t ctrl_trg; /**< Mirror of the trigger settings. */
132
133 volatile int mode; /**< Flags used for storing SW wraparound setup*/
134 int stop_mode; /**< The user defined stop condition flag. */
135 unsigned int start_mode;
136 unsigned int stop_count; /**< The user defined dates presentation end count. */
137 unsigned int stop_data_count; /**< The stop presentation count. */
138 unsigned int data_count; /**< The real presentation count. */
139 unsigned int preloaded_count; /**< The next data addres in buffer. <= for wraparound mode. */
140 int hardware_stop_delay; /**< The time that stop can take. This is only to not show hardware bug to user. */
141
142 volatile enum ME6000_AO_STATUS status; /**< The current stream status flag. */
143 me6000_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
144
145 /* Registers *//**< All registers are 32 bits long. */
146 unsigned long ctrl_reg;
147 unsigned long status_reg;
148 unsigned long fifo_reg;
149 unsigned long single_reg;
150 unsigned long timer_reg;
151 unsigned long irq_status_reg;
152 unsigned long preload_reg;
153 unsigned long irq_reset_reg;
154#ifdef MEDEBUG_DEBUG_REG
155 unsigned long reg_base;
156#endif
157
158 /* Software buffer */
159 me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. */
160 wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
161
162 struct workqueue_struct *me6000_workqueue;
163#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
164 struct work_struct ao_control_task;
165#else
166 struct delayed_work ao_control_task;
167#endif
168
169 volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
170
171} me6000_ao_subdevice_t;
172
173/**
174 * @brief The constructor to generate a ME-6000 analog output subdevice instance.
175 *
176 * @param reg_base The register base address of the device as returned by the PCI BIOS.
177 * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
178 * @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
179 * @param ao_idx Subdevice number.
180 * @param fifo Flag set if subdevice has hardware FIFO.
181 * @param irq IRQ number.
182 * @param high_range Flag set if subdevice has high curren output.
183 * @param me6000_wq Queue for asynchronous task (1 queue for all subdevice on 1 board).
184 *
185 * @return Pointer to new instance on success.\n
186 * NULL on error.
187 */
188me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
189 spinlock_t * preload_reg_lock,
190 uint32_t * preload_flags,
191 uint32_t * triggering_flags,
192 int ao_idx,
193 int fifo,
194 int irq,
195 int high_range,
196 struct workqueue_struct
197 *me6000_wq);
198
199#endif //__KERNEL__
200#endif //_ME6000_AO_H_
diff --git a/drivers/staging/meilhaus/me6000_ao_reg.h b/drivers/staging/meilhaus/me6000_ao_reg.h
new file mode 100644
index 000000000000..eb8f46e1b75b
--- /dev/null
+++ b/drivers/staging/meilhaus/me6000_ao_reg.h
@@ -0,0 +1,177 @@
1/**
2 * @file me6000_ao_reg.h
3 *
4 * @brief ME-6000 analog output subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME6000_AO_REG_H_
28#define _ME6000_AO_REG_H_
29
30#ifdef __KERNEL__
31
32// AO
33#define ME6000_AO_00_CTRL_REG 0x00 // R/W
34#define ME6000_AO_00_STATUS_REG 0x04 // R/_
35#define ME6000_AO_00_FIFO_REG 0x08 // _/W
36#define ME6000_AO_00_SINGLE_REG 0x0C // R/W
37#define ME6000_AO_00_TIMER_REG 0x10 // _/W
38
39#define ME6000_AO_01_CTRL_REG 0x18 // R/W
40#define ME6000_AO_01_STATUS_REG 0x1C // R/_
41#define ME6000_AO_01_FIFO_REG 0x20 // _/W
42#define ME6000_AO_01_SINGLE_REG 0x24 // R/W
43#define ME6000_AO_01_TIMER_REG 0x28 // _/W
44
45#define ME6000_AO_02_CTRL_REG 0x30 // R/W
46#define ME6000_AO_02_STATUS_REG 0x34 // R/_
47#define ME6000_AO_02_FIFO_REG 0x38 // _/W
48#define ME6000_AO_02_SINGLE_REG 0x3C // R/W
49#define ME6000_AO_02_TIMER_REG 0x40 // _/W
50
51#define ME6000_AO_03_CTRL_REG 0x48 // R/W
52#define ME6000_AO_03_STATUS_REG 0x4C // R/_
53#define ME6000_AO_03_FIFO_REG 0x50 // _/W
54#define ME6000_AO_03_SINGLE_REG 0x54 // R/W
55#define ME6000_AO_03_TIMER_REG 0x58 // _/W
56
57#define ME6000_AO_SINGLE_STATUS_REG 0xA4 // R/_
58#define ME6000_AO_SINGLE_STATUS_OFFSET 4 //The first single subdevice => bit 0 in ME6000_AO_SINGLE_STATUS_REG.
59
60#define ME6000_AO_04_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
61#define ME6000_AO_04_SINGLE_REG 0x74 // _/W
62
63#define ME6000_AO_05_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
64#define ME6000_AO_05_SINGLE_REG 0x78 // _/W
65
66#define ME6000_AO_06_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
67#define ME6000_AO_06_SINGLE_REG 0x7C // _/W
68
69#define ME6000_AO_07_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
70#define ME6000_AO_07_SINGLE_REG 0x80 // _/W
71
72#define ME6000_AO_08_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
73#define ME6000_AO_08_SINGLE_REG 0x84 // _/W
74
75#define ME6000_AO_09_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
76#define ME6000_AO_09_SINGLE_REG 0x88 // _/W
77
78#define ME6000_AO_10_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
79#define ME6000_AO_10_SINGLE_REG 0x8C // _/W
80
81#define ME6000_AO_11_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
82#define ME6000_AO_11_SINGLE_REG 0x90 // _/W
83
84#define ME6000_AO_12_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
85#define ME6000_AO_12_SINGLE_REG 0x94 // _/W
86
87#define ME6000_AO_13_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
88#define ME6000_AO_13_SINGLE_REG 0x98 // _/W
89
90#define ME6000_AO_14_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
91#define ME6000_AO_14_SINGLE_REG 0x9C // _/W
92
93#define ME6000_AO_15_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
94#define ME6000_AO_15_SINGLE_REG 0xA0 // _/W
95
96//ME6000_AO_CTRL_REG
97#define ME6000_AO_MODE_SINGLE 0x00
98#define ME6000_AO_MODE_WRAPAROUND 0x01
99#define ME6000_AO_MODE_CONTINUOUS 0x02
100#define ME6000_AO_CTRL_MODE_MASK (ME6000_AO_MODE_WRAPAROUND | ME6000_AO_MODE_CONTINUOUS)
101
102#define ME6000_AO_CTRL_BIT_MODE_WRAPAROUND 0x001
103#define ME6000_AO_CTRL_BIT_MODE_CONTINUOUS 0x002
104#define ME6000_AO_CTRL_BIT_STOP 0x004
105#define ME6000_AO_CTRL_BIT_ENABLE_FIFO 0x008
106#define ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG 0x010
107#define ME6000_AO_CTRL_BIT_EX_TRIG_EDGE 0x020
108#define ME6000_AO_CTRL_BIT_ENABLE_IRQ 0x040
109#define ME6000_AO_CTRL_BIT_IMMEDIATE_STOP 0x080
110#define ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH 0x800
111
112//ME6000_AO_STATUS_REG
113#define ME6000_AO_STATUS_BIT_FSM 0x01
114#define ME6000_AO_STATUS_BIT_FF 0x02
115#define ME6000_AO_STATUS_BIT_HF 0x04
116#define ME6000_AO_STATUS_BIT_EF 0x08
117
118#define ME6000_AO_PRELOAD_REG 0xA8 // R/W ///ME6000_AO_SYNC_REG <==> ME6000_AO_PRELOAD_REG
119/*
120#define ME6000_AO_SYNC_HOLD_0 0x00000001
121#define ME6000_AO_SYNC_HOLD_1 0x00000002
122#define ME6000_AO_SYNC_HOLD_2 0x00000004
123#define ME6000_AO_SYNC_HOLD_3 0x00000008
124#define ME6000_AO_SYNC_HOLD_4 0x00000010
125#define ME6000_AO_SYNC_HOLD_5 0x00000020
126#define ME6000_AO_SYNC_HOLD_6 0x00000040
127#define ME6000_AO_SYNC_HOLD_7 0x00000080
128#define ME6000_AO_SYNC_HOLD_8 0x00000100
129#define ME6000_AO_SYNC_HOLD_9 0x00000200
130#define ME6000_AO_SYNC_HOLD_10 0x00000400
131#define ME6000_AO_SYNC_HOLD_11 0x00000800
132#define ME6000_AO_SYNC_HOLD_12 0x00001000
133#define ME6000_AO_SYNC_HOLD_13 0x00002000
134#define ME6000_AO_SYNC_HOLD_14 0x00004000
135#define ME6000_AO_SYNC_HOLD_15 0x00008000
136*/
137#define ME6000_AO_SYNC_HOLD 0x00000001
138/*
139#define ME6000_AO_SYNC_EXT_TRIG_0 0x00010000
140#define ME6000_AO_SYNC_EXT_TRIG_1 0x00020000
141#define ME6000_AO_SYNC_EXT_TRIG_2 0x00040000
142#define ME6000_AO_SYNC_EXT_TRIG_3 0x00080000
143#define ME6000_AO_SYNC_EXT_TRIG_4 0x00100000
144#define ME6000_AO_SYNC_EXT_TRIG_5 0x00200000
145#define ME6000_AO_SYNC_EXT_TRIG_6 0x00400000
146#define ME6000_AO_SYNC_EXT_TRIG_7 0x00800000
147#define ME6000_AO_SYNC_EXT_TRIG_8 0x01000000
148#define ME6000_AO_SYNC_EXT_TRIG_9 0x02000000
149#define ME6000_AO_SYNC_EXT_TRIG_10 0x04000000
150#define ME6000_AO_SYNC_EXT_TRIG_11 0x08000000
151#define ME6000_AO_SYNC_EXT_TRIG_12 0x10000000
152#define ME6000_AO_SYNC_EXT_TRIG_13 0x20000000
153#define ME6000_AO_SYNC_EXT_TRIG_14 0x40000000
154#define ME6000_AO_SYNC_EXT_TRIG_15 0x80000000
155*/
156#define ME6000_AO_SYNC_EXT_TRIG 0x00010000
157
158#define ME6000_AO_EXT_TRIG 0x80000000
159
160// AO-IRQ
161#define ME6000_AO_IRQ_STATUS_REG 0x60 // R/_
162#define ME6000_AO_00_IRQ_RESET_REG 0x64 // R/_
163#define ME6000_AO_01_IRQ_RESET_REG 0x68 // R/_
164#define ME6000_AO_02_IRQ_RESET_REG 0x6C // R/_
165#define ME6000_AO_03_IRQ_RESET_REG 0x70 // R/_
166
167#define ME6000_IRQ_STATUS_BIT_0 0x01
168#define ME6000_IRQ_STATUS_BIT_1 0x02
169#define ME6000_IRQ_STATUS_BIT_2 0x04
170#define ME6000_IRQ_STATUS_BIT_3 0x08
171
172#define ME6000_IRQ_STATUS_BIT_AO_HF ME6000_IRQ_STATUS_BIT_0
173
174//DUMY register
175#define ME6000_AO_DUMY 0xFC
176#endif
177#endif
diff --git a/drivers/staging/meilhaus/me6000_device.c b/drivers/staging/meilhaus/me6000_device.c
new file mode 100644
index 000000000000..fee4c58b8464
--- /dev/null
+++ b/drivers/staging/meilhaus/me6000_device.c
@@ -0,0 +1,211 @@
1/**
2 * @file me6000_device.c
3 *
4 * @brief Device class template implementation.
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#ifndef MODULE
33# define MODULE
34#endif
35
36#include <linux/module.h>
37
38#include <linux/pci.h>
39#include <linux/slab.h>
40
41#include "meids.h"
42#include "meerror.h"
43#include "mecommon.h"
44#include "meinternal.h"
45
46#include "mefirmware.h"
47
48#include "mesubdevice.h"
49#include "medebug.h"
50#include "medevice.h"
51#include "me6000_reg.h"
52#include "me6000_device.h"
53#include "meplx_reg.h"
54#include "me6000_dio.h"
55#include "me6000_ao.h"
56
57/**
58 * @brief Global variable.
59 * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts).
60 */
61static struct workqueue_struct *me6000_workqueue;
62
63me_device_t *me6000_pci_constructor(struct pci_dev *pci_device)
64{
65 me6000_device_t *me6000_device;
66 me_subdevice_t *subdevice;
67 unsigned int version_idx;
68 int err;
69 int i;
70 int high_range = 0;
71 int fifo;
72
73 PDEBUG("executed.\n");
74
75 // Allocate structure for device instance.
76 me6000_device = kmalloc(sizeof(me6000_device_t), GFP_KERNEL);
77
78 if (!me6000_device) {
79 PERROR("Cannot get memory for device instance.\n");
80 return NULL;
81 }
82
83 memset(me6000_device, 0, sizeof(me6000_device_t));
84
85 // Initialize base class structure.
86 err = me_device_pci_init((me_device_t *) me6000_device, pci_device);
87
88 if (err) {
89 kfree(me6000_device);
90 PERROR("Cannot initialize device base class.\n");
91 return NULL;
92 }
93
94 /* Download the xilinx firmware */
95 err = me_xilinx_download(me6000_device->base.info.pci.reg_bases[1],
96 me6000_device->base.info.pci.reg_bases[2],
97 &pci_device->dev, "me6000.bin");
98
99 if (err) {
100 me_device_deinit((me_device_t *) me6000_device);
101 kfree(me6000_device);
102 PERROR("Can't download firmware.\n");
103 return NULL;
104 }
105
106 /* Get the index in the device version information table. */
107 version_idx =
108 me6000_versions_get_device_index(me6000_device->base.info.pci.
109 device_id);
110
111 // Initialize spin lock .
112 spin_lock_init(&me6000_device->preload_reg_lock);
113 spin_lock_init(&me6000_device->dio_ctrl_reg_lock);
114
115 /* Create digital input/output instances. */
116 for (i = 0; i < me6000_versions[version_idx].dio_subdevices; i++) {
117 subdevice =
118 (me_subdevice_t *) me6000_dio_constructor(me6000_device->
119 base.info.pci.
120 reg_bases[3], i,
121 &me6000_device->
122 dio_ctrl_reg_lock);
123
124 if (!subdevice) {
125 me_device_deinit((me_device_t *) me6000_device);
126 kfree(me6000_device);
127 PERROR("Cannot get memory for subdevice.\n");
128 return NULL;
129 }
130
131 me_slist_add_subdevice_tail(&me6000_device->base.slist,
132 subdevice);
133 }
134
135 /* Create analog output instances. */
136 for (i = 0; i < me6000_versions[version_idx].ao_subdevices; i++) {
137 high_range = ((i == 8)
138 &&
139 ((me6000_device->base.info.pci.device_id ==
140 PCI_DEVICE_ID_MEILHAUS_ME6359)
141 || (me6000_device->base.info.pci.device_id ==
142 PCI_DEVICE_ID_MEILHAUS_ME6259)
143 )
144 )? 1 : 0;
145
146 fifo =
147 (i <
148 me6000_versions[version_idx].
149 ao_fifo) ? ME6000_AO_HAS_FIFO : 0x0;
150 fifo |= (i < 4) ? ME6000_AO_EXTRA_HARDWARE : 0x0;
151
152 subdevice =
153 (me_subdevice_t *) me6000_ao_constructor(me6000_device->
154 base.info.pci.
155 reg_bases[2],
156 &me6000_device->
157 preload_reg_lock,
158 &me6000_device->
159 preload_flags,
160 &me6000_device->
161 triggering_flags,
162 i, fifo,
163 me6000_device->
164 base.irq,
165 high_range,
166 me6000_workqueue);
167
168 if (!subdevice) {
169 me_device_deinit((me_device_t *) me6000_device);
170 kfree(me6000_device);
171 PERROR("Cannot get memory for subdevice.\n");
172 return NULL;
173 }
174
175 me_slist_add_subdevice_tail(&me6000_device->base.slist,
176 subdevice);
177 }
178
179 return (me_device_t *) me6000_device;
180}
181
182// Init and exit of module.
183
184static int __init me6000_init(void)
185{
186 PDEBUG("executed.\n");
187
188 me6000_workqueue = create_singlethread_workqueue("me6000");
189 return 0;
190}
191
192static void __exit me6000_exit(void)
193{
194 PDEBUG("executed.\n");
195
196 flush_workqueue(me6000_workqueue);
197 destroy_workqueue(me6000_workqueue);
198}
199
200module_init(me6000_init);
201module_exit(me6000_exit);
202
203// Administrative stuff for modinfo.
204MODULE_AUTHOR
205 ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
206MODULE_DESCRIPTION("Device Driver Module for ME-6000 Device");
207MODULE_SUPPORTED_DEVICE("Meilhaus ME-6000 Devices");
208MODULE_LICENSE("GPL");
209
210// Export the constructor.
211EXPORT_SYMBOL(me6000_pci_constructor);
diff --git a/drivers/staging/meilhaus/me6000_device.h b/drivers/staging/meilhaus/me6000_device.h
new file mode 100644
index 000000000000..18cc7d1e14f1
--- /dev/null
+++ b/drivers/staging/meilhaus/me6000_device.h
@@ -0,0 +1,149 @@
1/**
2 * @file me6000_device.h
3 *
4 * @brief ME-6000 device class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME6000_DEVICE_H
28#define _ME6000_DEVICE_H
29
30#include <linux/pci.h>
31#include <linux/spinlock.h>
32
33#include "medevice.h"
34
35#ifdef __KERNEL__
36
37/**
38 * @brief Structure holding ME-6000 device capabilities.
39 */
40typedef struct me6000_version {
41 uint16_t device_id;
42 unsigned int dio_subdevices;
43 unsigned int ao_subdevices;
44 unsigned int ao_fifo; //How many devices have FIFO
45} me6000_version_t;
46
47/**
48 * @brief ME-6000 device capabilities.
49 */
50static me6000_version_t me6000_versions[] = {
51 {PCI_DEVICE_ID_MEILHAUS_ME6004, 0, 4, 0},
52 {PCI_DEVICE_ID_MEILHAUS_ME6008, 0, 8, 0},
53 {PCI_DEVICE_ID_MEILHAUS_ME600F, 0, 16, 0},
54
55 {PCI_DEVICE_ID_MEILHAUS_ME6014, 0, 4, 0},
56 {PCI_DEVICE_ID_MEILHAUS_ME6018, 0, 8, 0},
57 {PCI_DEVICE_ID_MEILHAUS_ME601F, 0, 16, 0},
58
59 {PCI_DEVICE_ID_MEILHAUS_ME6034, 0, 4, 0},
60 {PCI_DEVICE_ID_MEILHAUS_ME6038, 0, 8, 0},
61 {PCI_DEVICE_ID_MEILHAUS_ME603F, 0, 16, 0},
62
63 {PCI_DEVICE_ID_MEILHAUS_ME6104, 0, 4, 4},
64 {PCI_DEVICE_ID_MEILHAUS_ME6108, 0, 8, 4},
65 {PCI_DEVICE_ID_MEILHAUS_ME610F, 0, 16, 4},
66
67 {PCI_DEVICE_ID_MEILHAUS_ME6114, 0, 4, 4},
68 {PCI_DEVICE_ID_MEILHAUS_ME6118, 0, 8, 4},
69 {PCI_DEVICE_ID_MEILHAUS_ME611F, 0, 16, 4},
70
71 {PCI_DEVICE_ID_MEILHAUS_ME6134, 0, 4, 4},
72 {PCI_DEVICE_ID_MEILHAUS_ME6138, 0, 8, 4},
73 {PCI_DEVICE_ID_MEILHAUS_ME613F, 0, 16, 4},
74
75 {PCI_DEVICE_ID_MEILHAUS_ME6044, 2, 4, 0},
76 {PCI_DEVICE_ID_MEILHAUS_ME6048, 2, 8, 0},
77 {PCI_DEVICE_ID_MEILHAUS_ME604F, 2, 16, 0},
78
79 {PCI_DEVICE_ID_MEILHAUS_ME6054, 2, 4, 0},
80 {PCI_DEVICE_ID_MEILHAUS_ME6058, 2, 8, 0},
81 {PCI_DEVICE_ID_MEILHAUS_ME605F, 2, 16, 0},
82
83 {PCI_DEVICE_ID_MEILHAUS_ME6074, 2, 4, 0},
84 {PCI_DEVICE_ID_MEILHAUS_ME6078, 2, 8, 0},
85 {PCI_DEVICE_ID_MEILHAUS_ME607F, 2, 16, 0},
86
87 {PCI_DEVICE_ID_MEILHAUS_ME6144, 2, 4, 4},
88 {PCI_DEVICE_ID_MEILHAUS_ME6148, 2, 8, 4},
89 {PCI_DEVICE_ID_MEILHAUS_ME614F, 2, 16, 4},
90
91 {PCI_DEVICE_ID_MEILHAUS_ME6154, 2, 4, 4},
92 {PCI_DEVICE_ID_MEILHAUS_ME6158, 2, 8, 4},
93 {PCI_DEVICE_ID_MEILHAUS_ME615F, 2, 16, 4},
94
95 {PCI_DEVICE_ID_MEILHAUS_ME6174, 2, 4, 4},
96 {PCI_DEVICE_ID_MEILHAUS_ME6178, 2, 8, 4},
97 {PCI_DEVICE_ID_MEILHAUS_ME617F, 2, 16, 4},
98
99 {PCI_DEVICE_ID_MEILHAUS_ME6259, 2, 9, 0},
100
101 {PCI_DEVICE_ID_MEILHAUS_ME6359, 2, 9, 4},
102
103 {0},
104};
105
106#define ME6000_DEVICE_VERSIONS (sizeof(me6000_versions) / sizeof(me6000_version_t) - 1) /**< Returns the number of entries in #me6000_versions. */
107
108/**
109 * @brief Returns the index of the device entry in #me6000_versions.
110 *
111 * @param device_id The PCI device id of the device to query.
112 * @return The index of the device in #me6000_versions.
113 */
114static inline unsigned int me6000_versions_get_device_index(uint16_t device_id)
115{
116 unsigned int i;
117 for (i = 0; i < ME6000_DEVICE_VERSIONS; i++)
118 if (me6000_versions[i].device_id == device_id)
119 break;
120 return i;
121}
122
123/**
124 * @brief The ME-6000 device class structure.
125 */
126typedef struct me6000_device {
127 me_device_t base; /**< The Meilhaus device base class. */
128
129 /* Child class attributes. */
130 spinlock_t preload_reg_lock; /**< Guards the preload register. */
131 uint32_t preload_flags;
132 uint32_t triggering_flags;
133
134 spinlock_t dio_ctrl_reg_lock;
135} me6000_device_t;
136
137/**
138 * @brief The ME-6000 device class constructor.
139 *
140 * @param pci_device The pci device structure given by the PCI subsystem.
141 *
142 * @return On succes a new ME-6000 device instance. \n
143 * NULL on error.
144 */
145me_device_t *me6000_pci_constructor(struct pci_dev *pci_device)
146 __attribute__ ((weak));
147
148#endif
149#endif
diff --git a/drivers/staging/meilhaus/me6000_dio.c b/drivers/staging/meilhaus/me6000_dio.c
new file mode 100644
index 000000000000..07f1069f9ac6
--- /dev/null
+++ b/drivers/staging/meilhaus/me6000_dio.c
@@ -0,0 +1,415 @@
1/**
2 * @file me6000_dio.c
3 *
4 * @brief ME-6000 digital input/output 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45
46#include "medebug.h"
47#include "me6000_dio_reg.h"
48#include "me6000_dio.h"
49
50/*
51 * Defines
52 */
53
54/*
55 * Functions
56 */
57
58static int me6000_dio_io_reset_subdevice(struct me_subdevice *subdevice,
59 struct file *filep, int flags)
60{
61 me6000_dio_subdevice_t *instance;
62 uint8_t mode;
63
64 PDEBUG("executed.\n");
65
66 instance = (me6000_dio_subdevice_t *) subdevice;
67
68 if (flags) {
69 PERROR("Invalid flag specified.\n");
70 return ME_ERRNO_INVALID_FLAGS;
71 }
72
73 ME_SUBDEVICE_ENTER;
74
75 spin_lock(&instance->subdevice_lock);
76 spin_lock(instance->ctrl_reg_lock);
77 mode = inb(instance->ctrl_reg);
78 mode &= ~(0x3 << (instance->dio_idx * 2));
79 outb(mode, instance->ctrl_reg);
80 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
81 instance->ctrl_reg - instance->reg_base, mode);
82 spin_unlock(instance->ctrl_reg_lock);
83
84 outb(0x00, instance->port_reg);
85 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
86 instance->ctrl_reg - instance->reg_base, 0x00);
87 spin_unlock(&instance->subdevice_lock);
88
89 ME_SUBDEVICE_EXIT;
90
91 return ME_ERRNO_SUCCESS;
92}
93
94static int me6000_dio_io_single_config(me_subdevice_t * subdevice,
95 struct file *filep,
96 int channel,
97 int single_config,
98 int ref,
99 int trig_chan,
100 int trig_type, int trig_edge, int flags)
101{
102 me6000_dio_subdevice_t *instance;
103 int err = ME_ERRNO_SUCCESS;
104 uint8_t mode;
105 int size =
106 flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
107 | ME_IO_SINGLE_CONFIG_DIO_WORD |
108 ME_IO_SINGLE_CONFIG_DIO_DWORD);
109
110 PDEBUG("executed.\n");
111
112 instance = (me6000_dio_subdevice_t *) subdevice;
113
114 ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
115 spin_lock(instance->ctrl_reg_lock);
116 mode = inb(instance->ctrl_reg);
117 switch (size) {
118 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
119 case ME_IO_SINGLE_CONFIG_DIO_BYTE:
120 if (channel == 0) {
121 if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
122 mode &=
123 ~((ME6000_DIO_CTRL_BIT_MODE_0 |
124 ME6000_DIO_CTRL_BIT_MODE_1) <<
125 (instance->dio_idx * 2));
126 } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
127 mode &=
128 ~((ME6000_DIO_CTRL_BIT_MODE_0 |
129 ME6000_DIO_CTRL_BIT_MODE_1) <<
130 (instance->dio_idx * 2));
131 mode |=
132 ME6000_DIO_CTRL_BIT_MODE_0 << (instance->
133 dio_idx * 2);
134 } else {
135 PERROR
136 ("Invalid port configuration specified.\n");
137 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
138 }
139 } else {
140 PERROR("Invalid channel number.\n");
141 err = ME_ERRNO_INVALID_CHANNEL;
142 }
143 break;
144
145 default:
146 PERROR("Invalid flags.\n");
147 err = ME_ERRNO_INVALID_FLAGS;
148 }
149
150 if (!err) {
151 outb(mode, instance->ctrl_reg);
152 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
153 instance->reg_base,
154 instance->ctrl_reg - instance->reg_base, mode);
155 }
156 spin_unlock(instance->ctrl_reg_lock);
157 spin_unlock(&instance->subdevice_lock);
158
159 ME_SUBDEVICE_EXIT;
160
161 return err;
162}
163
164static int me6000_dio_io_single_read(me_subdevice_t * subdevice,
165 struct file *filep,
166 int channel,
167 int *value, int time_out, int flags)
168{
169 me6000_dio_subdevice_t *instance;
170 int err = ME_ERRNO_SUCCESS;
171 uint8_t mode;
172
173 PDEBUG("executed.\n");
174
175 instance = (me6000_dio_subdevice_t *) subdevice;
176
177 ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
178 spin_lock(instance->ctrl_reg_lock);
179 switch (flags) {
180 case ME_IO_SINGLE_TYPE_DIO_BIT:
181 if ((channel >= 0) && (channel < 8)) {
182 mode =
183 inb(instance->
184 ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
185 ME6000_DIO_CTRL_BIT_MODE_1) <<
186 (instance->dio_idx * 2));
187 if ((mode ==
188 (ME6000_DIO_CTRL_BIT_MODE_0 <<
189 (instance->dio_idx * 2))) || !mode) {
190 *value =
191 inb(instance->port_reg) & (0x1 << channel);
192 } else {
193 PERROR("Port not in output or input mode.\n");
194 err = ME_ERRNO_PREVIOUS_CONFIG;
195 }
196 } else {
197 PERROR("Invalid bit number specified.\n");
198 err = ME_ERRNO_INVALID_CHANNEL;
199 }
200 break;
201
202 case ME_IO_SINGLE_NO_FLAGS:
203 case ME_IO_SINGLE_TYPE_DIO_BYTE:
204 if (channel == 0) {
205 mode =
206 inb(instance->
207 ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
208 ME6000_DIO_CTRL_BIT_MODE_1) <<
209 (instance->dio_idx * 2));
210 if ((mode ==
211 (ME6000_DIO_CTRL_BIT_MODE_0 <<
212 (instance->dio_idx * 2))) || !mode) {
213 *value = inb(instance->port_reg) & 0x00FF;
214 } else {
215 PERROR("Port not in output or input mode.\n");
216 err = ME_ERRNO_PREVIOUS_CONFIG;
217 }
218 } else {
219 PERROR("Invalid byte number specified.\n");
220 err = ME_ERRNO_INVALID_CHANNEL;
221 }
222 break;
223
224 default:
225 PERROR("Invalid flags specified.\n");
226 err = ME_ERRNO_INVALID_FLAGS;
227 }
228 spin_unlock(instance->ctrl_reg_lock);
229 spin_unlock(&instance->subdevice_lock);
230
231 ME_SUBDEVICE_EXIT;
232
233 return err;
234}
235
236static int me6000_dio_io_single_write(me_subdevice_t * subdevice,
237 struct file *filep,
238 int channel,
239 int value, int time_out, int flags)
240{
241 me6000_dio_subdevice_t *instance;
242 int err = ME_ERRNO_SUCCESS;
243 uint8_t mode;
244 uint8_t byte;
245
246 PDEBUG("executed.\n");
247
248 instance = (me6000_dio_subdevice_t *) subdevice;
249
250 ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
251 spin_lock(instance->ctrl_reg_lock);
252 switch (flags) {
253 case ME_IO_SINGLE_TYPE_DIO_BIT:
254 if ((channel >= 0) && (channel < 8)) {
255 mode =
256 inb(instance->
257 ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
258 ME6000_DIO_CTRL_BIT_MODE_1) <<
259 (instance->dio_idx * 2));
260
261 if (mode ==
262 (ME6000_DIO_CTRL_BIT_MODE_0 <<
263 (instance->dio_idx * 2))) {
264 byte = inb(instance->port_reg) & 0x00FF;
265
266 if (value)
267 byte |= 0x1 << channel;
268 else
269 byte &= ~(0x1 << channel);
270
271 outb(byte, instance->port_reg);
272 } else {
273 PERROR("Port not in output or input mode.\n");
274 err = ME_ERRNO_PREVIOUS_CONFIG;
275 }
276 } else {
277 PERROR("Invalid bit number specified.\n");
278 err = ME_ERRNO_INVALID_CHANNEL;
279 }
280 break;
281
282 case ME_IO_SINGLE_NO_FLAGS:
283 case ME_IO_SINGLE_TYPE_DIO_BYTE:
284 if (channel == 0) {
285 mode =
286 inb(instance->
287 ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
288 ME6000_DIO_CTRL_BIT_MODE_1) <<
289 (instance->dio_idx * 2));
290
291 if (mode ==
292 (ME6000_DIO_CTRL_BIT_MODE_0 <<
293 (instance->dio_idx * 2))) {
294 outb(value, instance->port_reg);
295 } else {
296 PERROR("Port not in output or input mode.\n");
297 err = ME_ERRNO_PREVIOUS_CONFIG;
298 }
299 } else {
300 PERROR("Invalid byte number specified.\n");
301 err = ME_ERRNO_INVALID_CHANNEL;
302 }
303 break;
304
305 default:
306 PERROR("Invalid flags specified.\n");
307 err = ME_ERRNO_INVALID_FLAGS;
308 }
309 spin_unlock(instance->ctrl_reg_lock);
310 spin_unlock(&instance->subdevice_lock);
311
312 ME_SUBDEVICE_EXIT;
313
314 return err;
315}
316
317static int me6000_dio_query_number_channels(me_subdevice_t * subdevice,
318 int *number)
319{
320 PDEBUG("executed.\n");
321 *number = 8;
322 return ME_ERRNO_SUCCESS;
323}
324
325static int me6000_dio_query_subdevice_type(me_subdevice_t * subdevice,
326 int *type, int *subtype)
327{
328 PDEBUG("executed.\n");
329 *type = ME_TYPE_DIO;
330 *subtype = ME_SUBTYPE_SINGLE;
331 return ME_ERRNO_SUCCESS;
332}
333
334static int me6000_dio_query_subdevice_caps(me_subdevice_t * subdevice,
335 int *caps)
336{
337 PDEBUG("executed.\n");
338 *caps = ME_CAPS_DIO_DIR_BYTE;
339 return ME_ERRNO_SUCCESS;
340}
341
342me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base,
343 unsigned int dio_idx,
344 spinlock_t * ctrl_reg_lock)
345{
346 me6000_dio_subdevice_t *subdevice;
347 int err;
348
349 PDEBUG("executed.\n");
350
351 /* Allocate memory for subdevice instance */
352 subdevice = kmalloc(sizeof(me6000_dio_subdevice_t), GFP_KERNEL);
353
354 if (!subdevice) {
355 PERROR("Cannot get memory for subdevice instance.\n");
356 return NULL;
357 }
358
359 memset(subdevice, 0, sizeof(me6000_dio_subdevice_t));
360
361 /* Initialize subdevice base class */
362 err = me_subdevice_init(&subdevice->base);
363 if (err) {
364 PERROR("Cannot initialize subdevice base class instance.\n");
365 kfree(subdevice);
366 return NULL;
367 }
368
369 /* Set the subdevice ports */
370 subdevice->ctrl_reg = reg_base + ME6000_DIO_CTRL_REG;
371 switch (dio_idx) {
372 case 0:
373 subdevice->port_reg = reg_base + ME6000_DIO_PORT_0_REG;
374 break;
375 case 1:
376 subdevice->port_reg = reg_base + ME6000_DIO_PORT_1_REG;
377 break;
378 default:
379 err = ME_ERRNO_INVALID_SUBDEVICE;
380 }
381
382 if (err) {
383 PERROR("Cannot initialize subdevice base class instance.\n");
384 kfree(subdevice);
385 return NULL;
386 }
387 // Initialize spin locks.
388 spin_lock_init(&subdevice->subdevice_lock);
389
390 subdevice->ctrl_reg_lock = ctrl_reg_lock;
391
392 /* Save digital i/o index */
393 subdevice->dio_idx = dio_idx;
394
395#ifdef MEDEBUG_DEBUG_REG
396 subdevice->reg_base = reg_base;
397#endif
398
399 /* Overload base class methods. */
400 subdevice->base.me_subdevice_io_reset_subdevice =
401 me6000_dio_io_reset_subdevice;
402 subdevice->base.me_subdevice_io_single_config =
403 me6000_dio_io_single_config;
404 subdevice->base.me_subdevice_io_single_read = me6000_dio_io_single_read;
405 subdevice->base.me_subdevice_io_single_write =
406 me6000_dio_io_single_write;
407 subdevice->base.me_subdevice_query_number_channels =
408 me6000_dio_query_number_channels;
409 subdevice->base.me_subdevice_query_subdevice_type =
410 me6000_dio_query_subdevice_type;
411 subdevice->base.me_subdevice_query_subdevice_caps =
412 me6000_dio_query_subdevice_caps;
413
414 return subdevice;
415}
diff --git a/drivers/staging/meilhaus/me6000_dio.h b/drivers/staging/meilhaus/me6000_dio.h
new file mode 100644
index 000000000000..858bec1c4596
--- /dev/null
+++ b/drivers/staging/meilhaus/me6000_dio.h
@@ -0,0 +1,68 @@
1/**
2 * @file me6000_dio.h
3 *
4 * @brief ME-6000 digital input/output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME6000_DIO_H_
28#define _ME6000_DIO_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me6000_dio_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
44 unsigned int dio_idx; /**< The index of the digital i/o on the device. */
45
46 unsigned long port_reg; /**< Register holding the port status. */
47 unsigned long ctrl_reg; /**< Register to configure the port direction. */
48#ifdef MEDEBUG_DEBUG_REG
49 unsigned long reg_base;
50#endif
51} me6000_dio_subdevice_t;
52
53/**
54 * @brief The constructor to generate a ME-6000 digital input/ouput subdevice instance.
55 *
56 * @param reg_base The register base address of the device as returned by the PCI BIOS.
57 * @param dio_idx The index of the digital i/o port on the device.
58 * @param ctrl_reg_lock Spin lock protecting the control register.
59 *
60 * @return Pointer to new instance on success.\n
61 * NULL on error.
62 */
63me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base,
64 unsigned int dio_idx,
65 spinlock_t * ctrl_reg_lock);
66
67#endif
68#endif
diff --git a/drivers/staging/meilhaus/me6000_dio_reg.h b/drivers/staging/meilhaus/me6000_dio_reg.h
new file mode 100644
index 000000000000..e67a791a1e69
--- /dev/null
+++ b/drivers/staging/meilhaus/me6000_dio_reg.h
@@ -0,0 +1,43 @@
1/**
2 * @file me6000_dio_reg.h
3 *
4 * @brief ME-6000 digital input/output subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME6000_DIO_REG_H_
28#define _ME6000_DIO_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME6000_DIO_CTRL_REG 0x00 // R/W
33#define ME6000_DIO_PORT_0_REG 0x01 // R/W
34#define ME6000_DIO_PORT_1_REG 0x02 // R/W
35#define ME6000_DIO_PORT_REG ME6000_DIO_PORT_0_REG // R/W
36
37#define ME6000_DIO_CTRL_BIT_MODE_0 0x01
38#define ME6000_DIO_CTRL_BIT_MODE_1 0x02
39#define ME6000_DIO_CTRL_BIT_MODE_2 0x04
40#define ME6000_DIO_CTRL_BIT_MODE_3 0x08
41
42#endif
43#endif
diff --git a/drivers/staging/meilhaus/me6000_reg.h b/drivers/staging/meilhaus/me6000_reg.h
new file mode 100644
index 000000000000..d35273003415
--- /dev/null
+++ b/drivers/staging/meilhaus/me6000_reg.h
@@ -0,0 +1,35 @@
1/**
2 * @file me6000_reg.h
3 *
4 * @brief ME-6000 device register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME6000_REG_H_
28#define _ME6000_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME6000_INIT_XILINX_REG 0xAC // R/-
33
34#endif
35#endif
diff --git a/drivers/staging/meilhaus/me8100_device.c b/drivers/staging/meilhaus/me8100_device.c
new file mode 100644
index 000000000000..1fb79e490261
--- /dev/null
+++ b/drivers/staging/meilhaus/me8100_device.c
@@ -0,0 +1,187 @@
1/**
2 * @file me8100_device.c
3 *
4 * @brief ME-8100 device class implementation.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef __KERNEL__
28# define __KERNEL__
29#endif
30
31#ifndef MODULE
32# define MODULE
33#endif
34
35#include <linux/module.h>
36
37#include <linux/pci.h>
38#include <linux/slab.h>
39
40#include "meids.h"
41#include "meerror.h"
42#include "mecommon.h"
43#include "meinternal.h"
44
45#include "medebug.h"
46#include "medevice.h"
47#include "me8100_device.h"
48#include "mesubdevice.h"
49#include "me8100_di.h"
50#include "me8100_do.h"
51#include "me8254.h"
52
53me_device_t *me8100_pci_constructor(struct pci_dev *pci_device)
54{
55 me8100_device_t *me8100_device;
56 me_subdevice_t *subdevice;
57 unsigned int version_idx;
58 int err;
59 int i;
60
61 PDEBUG("executed.\n");
62
63 // Allocate structure for device instance.
64 me8100_device = kmalloc(sizeof(me8100_device_t), GFP_KERNEL);
65
66 if (!me8100_device) {
67 PERROR("Cannot get memory for device instance.\n");
68 return NULL;
69 }
70
71 memset(me8100_device, 0, sizeof(me8100_device_t));
72
73 // Initialize base class structure.
74 err = me_device_pci_init((me_device_t *) me8100_device, pci_device);
75
76 if (err) {
77 kfree(me8100_device);
78 PERROR("Cannot initialize device base class.\n");
79 return NULL;
80 }
81
82 /* Get the index in the device version information table. */
83 version_idx =
84 me8100_versions_get_device_index(me8100_device->base.info.pci.
85 device_id);
86
87 // Initialize spin lock .
88 spin_lock_init(&me8100_device->dio_ctrl_reg_lock);
89 spin_lock_init(&me8100_device->ctr_ctrl_reg_lock);
90 spin_lock_init(&me8100_device->clk_src_reg_lock);
91
92 // Create subdevice instances.
93
94 for (i = 0; i < me8100_versions[version_idx].di_subdevices; i++) {
95 subdevice =
96 (me_subdevice_t *) me8100_di_constructor(me8100_device->
97 base.info.pci.
98 reg_bases[2],
99 me8100_device->
100 base.info.pci.
101 reg_bases[1], i,
102 me8100_device->
103 base.irq,
104 &me8100_device->
105 dio_ctrl_reg_lock);
106
107 if (!subdevice) {
108 me_device_deinit((me_device_t *) me8100_device);
109 kfree(me8100_device);
110 PERROR("Cannot get memory for subdevice.\n");
111 return NULL;
112 }
113
114 me_slist_add_subdevice_tail(&me8100_device->base.slist,
115 subdevice);
116 }
117
118 for (i = 0; i < me8100_versions[version_idx].do_subdevices; i++) {
119 subdevice =
120 (me_subdevice_t *) me8100_do_constructor(me8100_device->
121 base.info.pci.
122 reg_bases[2], i,
123 &me8100_device->
124 dio_ctrl_reg_lock);
125
126 if (!subdevice) {
127 me_device_deinit((me_device_t *) me8100_device);
128 kfree(me8100_device);
129 PERROR("Cannot get memory for subdevice.\n");
130 return NULL;
131 }
132
133 me_slist_add_subdevice_tail(&me8100_device->base.slist,
134 subdevice);
135 }
136
137 for (i = 0; i < me8100_versions[version_idx].ctr_subdevices; i++) {
138 subdevice =
139 (me_subdevice_t *) me8254_constructor(me8100_device->base.
140 info.pci.device_id,
141 me8100_device->base.
142 info.pci.reg_bases[2],
143 0, i,
144 &me8100_device->
145 ctr_ctrl_reg_lock,
146 &me8100_device->
147 clk_src_reg_lock);
148
149 if (!subdevice) {
150 me_device_deinit((me_device_t *) me8100_device);
151 kfree(me8100_device);
152 PERROR("Cannot get memory for subdevice.\n");
153 return NULL;
154 }
155
156 me_slist_add_subdevice_tail(&me8100_device->base.slist,
157 subdevice);
158 }
159
160 return (me_device_t *) me8100_device;
161}
162
163// Init and exit of module.
164
165static int __init me8100_init(void)
166{
167 PDEBUG("executed.\n.");
168 return ME_ERRNO_SUCCESS;
169}
170
171static void __exit me8100_exit(void)
172{
173 PDEBUG("executed.\n.");
174}
175
176module_init(me8100_init);
177
178module_exit(me8100_exit);
179
180// Administrative stuff for modinfo.
181MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
182MODULE_DESCRIPTION("Device Driver Module for Template Device");
183MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
184MODULE_LICENSE("GPL");
185
186// Export the constructor.
187EXPORT_SYMBOL(me8100_pci_constructor);
diff --git a/drivers/staging/meilhaus/me8100_device.h b/drivers/staging/meilhaus/me8100_device.h
new file mode 100644
index 000000000000..44c42efb04e2
--- /dev/null
+++ b/drivers/staging/meilhaus/me8100_device.h
@@ -0,0 +1,97 @@
1/**
2 * @file me8100_device.h
3 *
4 * @brief ME-8100 device class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8100_DEVICE_H
28#define _ME8100_DEVICE_H
29
30#include <linux/pci.h>
31#include <linux/spinlock.h>
32
33#include "medevice.h"
34
35#ifdef __KERNEL__
36
37/**
38 * @brief Structure holding ME-8100 device capabilities.
39 */
40typedef struct me8100_version {
41 uint16_t device_id;
42 unsigned int di_subdevices;
43 unsigned int do_subdevices;
44 unsigned int ctr_subdevices;
45} me8100_version_t;
46
47/**
48 * @brief Device capabilities.
49 */
50static me8100_version_t me8100_versions[] = {
51 {PCI_DEVICE_ID_MEILHAUS_ME8100_A, 1, 1, 3},
52 {PCI_DEVICE_ID_MEILHAUS_ME8100_B, 2, 2, 3},
53 {0},
54};
55
56#define ME8100_DEVICE_VERSIONS (sizeof(me8100_versions) / sizeof(me8100_version_t) - 1) /**< Returns the number of entries in #me8100_versions. */
57
58/**
59 * @brief Returns the index of the device entry in #me8100_versions.
60 *
61 * @param device_id The PCI device id of the device to query.
62 * @return The index of the device in #me8100_versions.
63 */
64static inline unsigned int me8100_versions_get_device_index(uint16_t device_id)
65{
66 unsigned int i;
67 for (i = 0; i < ME8100_DEVICE_VERSIONS; i++)
68 if (me8100_versions[i].device_id == device_id)
69 break;
70 return i;
71}
72
73/**
74 * @brief The ME-8100 device class structure.
75 */
76typedef struct me8100_device {
77 me_device_t base; /**< The Meilhaus device base class. */
78
79 /* Child class attributes. */
80 spinlock_t dio_ctrl_reg_lock;
81 spinlock_t ctr_ctrl_reg_lock;
82 spinlock_t clk_src_reg_lock;
83} me8100_device_t;
84
85/**
86 * @brief The ME-8100 device class constructor.
87 *
88 * @param pci_device The pci device structure given by the PCI subsystem.
89 *
90 * @return On succes a new ME-8100 device instance. \n
91 * NULL on error.
92 */
93me_device_t *me8100_pci_constructor(struct pci_dev *pci_device)
94 __attribute__ ((weak));
95
96#endif
97#endif
diff --git a/drivers/staging/meilhaus/me8100_di.c b/drivers/staging/meilhaus/me8100_di.c
new file mode 100644
index 000000000000..0f146371b9a0
--- /dev/null
+++ b/drivers/staging/meilhaus/me8100_di.c
@@ -0,0 +1,693 @@
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
62static 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
117static 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
211static 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
318static 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
361static 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
408static 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
469static 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
477static 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
486static 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
493static 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)
507static irqreturn_t me8100_isr(int irq, void *dev_id)
508#else
509static 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, __FUNCTION__, 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, __FUNCTION__, icsr);
551 return IRQ_NONE;
552 }
553 } else {
554 PERROR("%s():Wrong interrupt idx=%d csr=0x%X.\n", __FUNCTION__,
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
597me8100_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}
diff --git a/drivers/staging/meilhaus/me8100_di.h b/drivers/staging/meilhaus/me8100_di.h
new file mode 100644
index 000000000000..e1db79129175
--- /dev/null
+++ b/drivers/staging/meilhaus/me8100_di.h
@@ -0,0 +1,89 @@
1/**
2 * @file me8100_di.h
3 *
4 * @brief ME-8100 digital input subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8100_DI_H_
28#define _ME8100_DI_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me8100_di_subdevice {
38 // Inheritance
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock;
44
45 unsigned di_idx;
46
47 int irq;
48 volatile int rised;
49 unsigned int irq_count;
50
51 uint status_flag; /**< Default interupt status flag */
52 uint status_value; /**< Interupt status */
53 uint status_value_edges; /**< Extended interupt status */
54 uint line_value;
55
56 uint16_t compare_value;
57 uint8_t filtering_flag;
58
59 wait_queue_head_t wait_queue;
60
61 unsigned long ctrl_reg;
62 unsigned long port_reg;
63 unsigned long mask_reg;
64 unsigned long pattern_reg;
65 unsigned long long din_int_reg;
66 unsigned long irq_reset_reg;
67 unsigned long irq_status_reg;
68#ifdef MEDEBUG_DEBUG_REG
69 unsigned long reg_base;
70#endif
71
72} me8100_di_subdevice_t;
73
74/**
75 * @brief The constructor to generate a ME-8100 digital input subdevice instance.
76 *
77 * @param reg_base The register base address of the device as returned by the PCI BIOS.
78 *
79 * @return Pointer to new instance on success.\n
80 * NULL on error.
81 */
82me8100_di_subdevice_t *me8100_di_constructor(uint32_t me8100_reg_base,
83 uint32_t plx_reg_base,
84 unsigned int di_idx,
85 int irq,
86 spinlock_t * ctrl_leg_lock);
87
88#endif
89#endif
diff --git a/drivers/staging/meilhaus/me8100_di_reg.h b/drivers/staging/meilhaus/me8100_di_reg.h
new file mode 100644
index 000000000000..063bd193709e
--- /dev/null
+++ b/drivers/staging/meilhaus/me8100_di_reg.h
@@ -0,0 +1,47 @@
1/**
2 * @file me8100_di_reg.h
3 *
4 * @brief ME-8100 digital input subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8100_DI_REG_H_
28#define _ME8100_DI_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME8100_RES_INT_REG_A 0x02 //(r, )
33#define ME8100_DI_REG_A 0x04 //(r, )
34#define ME8100_PATTERN_REG_A 0x08 //( ,w)
35#define ME8100_MASK_REG_A 0x0A //( ,w)
36#define ME8100_INT_DI_REG_A 0x0A //(r, )
37
38#define ME8100_RES_INT_REG_B 0x0E //(r, )
39#define ME8100_DI_REG_B 0x10 //(r, )
40#define ME8100_PATTERN_REG_B 0x14 //( ,w)
41#define ME8100_MASK_REG_B 0x16 //( ,w)
42#define ME8100_INT_DI_REG_B 0x16 //(r, )
43
44#define ME8100_REG_OFFSET 0x0C
45
46#endif
47#endif
diff --git a/drivers/staging/meilhaus/me8100_do.c b/drivers/staging/meilhaus/me8100_do.c
new file mode 100644
index 000000000000..957b9f92f760
--- /dev/null
+++ b/drivers/staging/meilhaus/me8100_do.c
@@ -0,0 +1,391 @@
1/**
2 * @file me8100_do.c
3 *
4 * @brief ME-8100 digital output 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45
46#include "medebug.h"
47#include "me8100_reg.h"
48#include "me8100_do_reg.h"
49#include "me8100_do.h"
50
51/*
52 * Defines
53 */
54
55/*
56 * Functions
57 */
58
59static int me8100_do_io_reset_subdevice(struct me_subdevice *subdevice,
60 struct file *filep, int flags)
61{
62 me8100_do_subdevice_t *instance;
63 uint16_t ctrl;
64
65 PDEBUG("executed.\n");
66
67 instance = (me8100_do_subdevice_t *) subdevice;
68
69 if (flags) {
70 PERROR("Invalid flag specified.\n");
71 return ME_ERRNO_INVALID_FLAGS;
72 }
73
74 ME_SUBDEVICE_ENTER;
75
76 spin_lock(&instance->subdevice_lock);
77 spin_lock(instance->ctrl_reg_lock);
78 ctrl = inw(instance->ctrl_reg);
79 ctrl &= ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0;
80 outw(ctrl, instance->ctrl_reg);
81 PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
82 instance->ctrl_reg - instance->reg_base, ctrl);
83 spin_unlock(instance->ctrl_reg_lock);
84 outw(0, instance->port_reg);
85 instance->port_reg_mirror = 0;
86 PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
87 instance->port_reg - instance->reg_base, 0);
88 spin_unlock(&instance->subdevice_lock);
89
90 ME_SUBDEVICE_EXIT;
91
92 return ME_ERRNO_SUCCESS;
93}
94
95static int me8100_do_io_single_config(me_subdevice_t * subdevice,
96 struct file *filep,
97 int channel,
98 int single_config,
99 int ref,
100 int trig_chan,
101 int trig_type, int trig_edge, int flags)
102{
103 me8100_do_subdevice_t *instance;
104 int err = ME_ERRNO_SUCCESS;
105 int config;
106
107 PDEBUG("executed.\n");
108
109 instance = (me8100_do_subdevice_t *) subdevice;
110
111 ME_SUBDEVICE_ENTER;
112
113 spin_lock(&instance->subdevice_lock);
114 spin_lock(instance->ctrl_reg_lock);
115 config = inw(instance->ctrl_reg);
116 switch (flags) {
117 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
118 case ME_IO_SINGLE_CONFIG_DIO_WORD:
119 if (channel == 0) {
120 if (single_config ==
121 ME_SINGLE_CONFIG_DIO_HIGH_IMPEDANCE) {
122 config &= ~(ME8100_DIO_CTRL_BIT_ENABLE_DIO);
123 } else if (single_config == ME_SINGLE_CONFIG_DIO_SINK) {
124 config |= ME8100_DIO_CTRL_BIT_ENABLE_DIO;
125 config &= ~ME8100_DIO_CTRL_BIT_SOURCE;
126 } else if (single_config == ME_SINGLE_CONFIG_DIO_SOURCE) {
127 config |=
128 ME8100_DIO_CTRL_BIT_ENABLE_DIO |
129 ME8100_DIO_CTRL_BIT_SOURCE;
130 } else {
131 PERROR
132 ("Invalid port configuration specified.\n");
133 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
134 }
135 } else {
136 PERROR("Invalid word number specified.\n");
137 err = ME_ERRNO_INVALID_CHANNEL;
138 }
139 break;
140
141 default:
142 PERROR("Invalid flags specified.\n");
143 err = ME_ERRNO_INVALID_FLAGS;
144 }
145
146 if (!err) {
147 outw(config, instance->ctrl_reg);
148 PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n",
149 instance->reg_base,
150 instance->ctrl_reg - instance->reg_base, config);
151 }
152
153 spin_unlock(instance->ctrl_reg_lock);
154 spin_unlock(&instance->subdevice_lock);
155
156 ME_SUBDEVICE_EXIT;
157
158 return err;
159}
160
161static int me8100_do_io_single_read(me_subdevice_t * subdevice,
162 struct file *filep,
163 int channel,
164 int *value, int time_out, int flags)
165{
166 me8100_do_subdevice_t *instance;
167 int err = ME_ERRNO_SUCCESS;
168
169 PDEBUG("executed.\n");
170
171 instance = (me8100_do_subdevice_t *) subdevice;
172
173 ME_SUBDEVICE_ENTER;
174
175 spin_lock(&instance->subdevice_lock);
176 switch (flags) {
177 case ME_IO_SINGLE_TYPE_DIO_BIT:
178 if ((channel >= 0) && (channel < 16)) {
179 *value = instance->port_reg_mirror & (0x1 << channel);
180 } else {
181 PERROR("Invalid bit number specified.\n");
182 err = ME_ERRNO_INVALID_CHANNEL;
183 }
184 break;
185
186 case ME_IO_SINGLE_TYPE_DIO_BYTE:
187 if (channel == 0) {
188 *value = instance->port_reg_mirror & 0xFF;
189 } else if (channel == 1) {
190 *value = (instance->port_reg_mirror >> 8) & 0xFF;
191 } else {
192 PERROR("Invalid byte number specified.\n");
193 err = ME_ERRNO_INVALID_CHANNEL;
194 }
195 break;
196
197 case ME_IO_SINGLE_NO_FLAGS:
198 case ME_IO_SINGLE_TYPE_DIO_WORD:
199 if (channel == 0) {
200 *value = instance->port_reg_mirror;
201 } else {
202 PERROR("Invalid word number specified.\n");
203 err = ME_ERRNO_INVALID_CHANNEL;
204 }
205 break;
206
207 default:
208 PERROR("Invalid flags specified.\n");
209 err = ME_ERRNO_INVALID_FLAGS;
210 }
211 spin_unlock(&instance->subdevice_lock);
212
213 ME_SUBDEVICE_EXIT;
214
215 return err;
216}
217
218static int me8100_do_io_single_write(me_subdevice_t * subdevice,
219 struct file *filep,
220 int channel,
221 int value, int time_out, int flags)
222{
223 me8100_do_subdevice_t *instance;
224 int err = ME_ERRNO_SUCCESS;
225
226 PDEBUG("executed.\n");
227
228 instance = (me8100_do_subdevice_t *) subdevice;
229
230 ME_SUBDEVICE_ENTER;
231
232 spin_lock(&instance->subdevice_lock);
233 switch (flags) {
234 case ME_IO_SINGLE_TYPE_DIO_BIT:
235 if ((channel >= 0) && (channel < 16)) {
236 instance->port_reg_mirror =
237 value ? (instance->
238 port_reg_mirror | (0x1 << channel))
239 : (instance->port_reg_mirror & ~(0x1 << channel));
240 outw(instance->port_reg_mirror, instance->port_reg);
241 PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
242 instance->reg_base,
243 instance->port_reg - instance->reg_base,
244 instance->port_reg_mirror);
245 } else {
246 PERROR("Invalid bit number specified.\n");
247 err = ME_ERRNO_INVALID_CHANNEL;
248 }
249 break;
250
251 case ME_IO_SINGLE_TYPE_DIO_BYTE:
252 if (channel == 0) {
253 instance->port_reg_mirror &= ~0xFF;
254 instance->port_reg_mirror |= value & 0xFF;
255 outw(instance->port_reg_mirror, instance->port_reg);
256 PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
257 instance->reg_base,
258 instance->port_reg - instance->reg_base,
259 instance->port_reg_mirror);
260 } else if (channel == 1) {
261 instance->port_reg_mirror &= ~0xFF00;
262 instance->port_reg_mirror |= (value << 8) & 0xFF00;
263 outw(instance->port_reg_mirror, instance->port_reg);
264 PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
265 instance->reg_base,
266 instance->port_reg - instance->reg_base,
267 instance->port_reg_mirror);
268 } else {
269 PERROR("Invalid byte number specified.\n");
270 err = ME_ERRNO_INVALID_CHANNEL;
271 }
272 break;
273
274 case ME_IO_SINGLE_NO_FLAGS:
275 case ME_IO_SINGLE_TYPE_DIO_WORD:
276 if (channel == 0) {
277 instance->port_reg_mirror = value;
278 outw(value, instance->port_reg);
279 PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
280 instance->reg_base,
281 instance->port_reg - instance->reg_base,
282 value);
283 } else {
284 PERROR("Invalid byte number specified.\n");
285 err = ME_ERRNO_INVALID_CHANNEL;
286 }
287 break;
288
289 default:
290 PERROR("Invalid flags specified.\n");
291 err = ME_ERRNO_INVALID_FLAGS;
292 }
293 spin_unlock(&instance->subdevice_lock);
294
295 ME_SUBDEVICE_EXIT;
296
297 return err;
298}
299
300static int me8100_do_query_number_channels(me_subdevice_t * subdevice,
301 int *number)
302{
303 PDEBUG("executed.\n");
304 *number = 16;
305 return ME_ERRNO_SUCCESS;
306}
307
308static int me8100_do_query_subdevice_type(me_subdevice_t * subdevice,
309 int *type, int *subtype)
310{
311 PDEBUG("executed.\n");
312 *type = ME_TYPE_DO;
313 *subtype = ME_SUBTYPE_SINGLE;
314 return ME_ERRNO_SUCCESS;
315}
316
317static int me8100_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
318{
319 PDEBUG("executed.\n");
320 *caps = ME_CAPS_DIO_SINK_SOURCE;
321 return ME_ERRNO_SUCCESS;
322}
323
324me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base,
325 unsigned int do_idx,
326 spinlock_t * ctrl_reg_lock)
327{
328 me8100_do_subdevice_t *subdevice;
329 int err;
330
331 PDEBUG("executed.\n");
332
333 /* Allocate memory for subdevice instance */
334 subdevice = kmalloc(sizeof(me8100_do_subdevice_t), GFP_KERNEL);
335
336 if (!subdevice) {
337 PERROR("Cannot get memory for subdevice instance.\n");
338 return NULL;
339 }
340
341 memset(subdevice, 0, sizeof(me8100_do_subdevice_t));
342
343 /* Initialize subdevice base class */
344 err = me_subdevice_init(&subdevice->base);
345
346 if (err) {
347 PERROR("Cannot initialize subdevice base class instance.\n");
348 kfree(subdevice);
349 return NULL;
350 }
351
352 /* Initialize registers */
353 if (do_idx == 0) {
354 subdevice->port_reg = reg_base + ME8100_DO_REG_A;
355 subdevice->ctrl_reg = reg_base + ME8100_CTRL_REG_A;
356 } else if (do_idx == 1) {
357 subdevice->port_reg = reg_base + ME8100_DO_REG_B;
358 subdevice->ctrl_reg = reg_base + ME8100_CTRL_REG_B;
359 } else {
360 PERROR("Wrong subdevice idx=%d.\n", do_idx);
361 kfree(subdevice);
362 return NULL;
363 }
364#ifdef MEDEBUG_DEBUG_REG
365 subdevice->reg_base = reg_base;
366#endif
367
368 // Initialize spin locks.
369 spin_lock_init(&subdevice->subdevice_lock);
370 subdevice->ctrl_reg_lock = ctrl_reg_lock;
371
372 /* Save the subdevice index */
373 subdevice->do_idx = do_idx;
374
375 /* Overload base class methods. */
376 subdevice->base.me_subdevice_io_reset_subdevice =
377 me8100_do_io_reset_subdevice;
378 subdevice->base.me_subdevice_io_single_config =
379 me8100_do_io_single_config;
380 subdevice->base.me_subdevice_io_single_read = me8100_do_io_single_read;
381 subdevice->base.me_subdevice_io_single_write =
382 me8100_do_io_single_write;
383 subdevice->base.me_subdevice_query_number_channels =
384 me8100_do_query_number_channels;
385 subdevice->base.me_subdevice_query_subdevice_type =
386 me8100_do_query_subdevice_type;
387 subdevice->base.me_subdevice_query_subdevice_caps =
388 me8100_do_query_subdevice_caps;
389
390 return subdevice;
391}
diff --git a/drivers/staging/meilhaus/me8100_do.h b/drivers/staging/meilhaus/me8100_do.h
new file mode 100644
index 000000000000..acf880136663
--- /dev/null
+++ b/drivers/staging/meilhaus/me8100_do.h
@@ -0,0 +1,70 @@
1/**
2 * @file me8100_do.h
3 *
4 * @brief ME-8100 digital output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8100_DO_H_
28#define _ME8100_DO_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me8100_do_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect the #ctrl_reg. */
44
45 unsigned int do_idx;
46
47 uint16_t port_reg_mirror; /**< Mirror used to store current port register setting which is write only. */
48
49 unsigned long port_reg; /**< Register holding the port status. */
50 unsigned long ctrl_reg; /**< Control register. */
51#ifdef MEDEBUG_DEBUG_REG
52 unsigned long reg_base;
53#endif
54} me8100_do_subdevice_t;
55
56/**
57 * @brief The constructor to generate a ME-8100 digital output subdevice instance.
58 *
59 * @param reg_base The register base address of the device as returned by the PCI BIOS.
60 * @param do_idx The index of the digital output subdevice on this device.
61 *
62 * @return Pointer to new instance on success.\n
63 * NULL on error.
64 */
65me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base,
66 unsigned int do_idx,
67 spinlock_t * ctrl_reg_lock);
68
69#endif
70#endif
diff --git a/drivers/staging/meilhaus/me8100_do_reg.h b/drivers/staging/meilhaus/me8100_do_reg.h
new file mode 100644
index 000000000000..13a23802b31a
--- /dev/null
+++ b/drivers/staging/meilhaus/me8100_do_reg.h
@@ -0,0 +1,36 @@
1/**
2 * @file me8100_ao_reg.h
3 *
4 * @brief ME-8100 analog output subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8100_DO_REG_H_
28#define _ME8100_DO_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME8100_DO_REG_A 0x06 //( ,w)
33#define ME8100_DO_REG_B 0x12 //( ,w)
34
35#endif
36#endif
diff --git a/drivers/staging/meilhaus/me8100_reg.h b/drivers/staging/meilhaus/me8100_reg.h
new file mode 100644
index 000000000000..d8c4b1c6b153
--- /dev/null
+++ b/drivers/staging/meilhaus/me8100_reg.h
@@ -0,0 +1,41 @@
1/**
2 * @file me8100_reg.h
3 *
4 * @brief ME-8100 register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8100_REG_H_
28#define _ME8100_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME8100_CTRL_REG_A 0x00 //( ,w)
33#define ME8100_CTRL_REG_B 0x0C //( ,w)
34
35#define ME8100_DIO_CTRL_BIT_SOURCE 0x10
36#define ME8100_DIO_CTRL_BIT_INTB_1 0x20
37#define ME8100_DIO_CTRL_BIT_INTB_0 0x40
38#define ME8100_DIO_CTRL_BIT_ENABLE_DIO 0x80
39
40#endif
41#endif
diff --git a/drivers/staging/meilhaus/me8200_device.c b/drivers/staging/meilhaus/me8200_device.c
new file mode 100644
index 000000000000..261c0cbd9d0a
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_device.c
@@ -0,0 +1,194 @@
1/**
2 * @file me8200_device.c
3 *
4 * @brief ME-8200 device class implementation.
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#ifndef MODULE
33# define MODULE
34#endif
35
36#include <linux/module.h>
37
38#include <linux/pci.h>
39#include <linux/slab.h>
40
41#include "meids.h"
42#include "meerror.h"
43#include "mecommon.h"
44#include "meinternal.h"
45
46#include "medebug.h"
47#include "meplx_reg.h"
48#include "medevice.h"
49#include "me8200_device.h"
50#include "mesubdevice.h"
51#include "me8200_di.h"
52#include "me8200_do.h"
53#include "me8200_dio.h"
54
55me_device_t *me8200_pci_constructor(struct pci_dev *pci_device)
56{
57 me8200_device_t *me8200_device;
58 me_subdevice_t *subdevice;
59 unsigned int version_idx;
60 int err;
61 int i;
62
63 PDEBUG("executed.\n");
64
65 // Allocate structure for device instance.
66 me8200_device = kmalloc(sizeof(me8200_device_t), GFP_KERNEL);
67
68 if (!me8200_device) {
69 PERROR("Cannot get memory for device instance.\n");
70 return NULL;
71 }
72
73 memset(me8200_device, 0, sizeof(me8200_device_t));
74
75 // Initialize base class structure.
76 err = me_device_pci_init((me_device_t *) me8200_device, pci_device);
77
78 if (err) {
79 kfree(me8200_device);
80 PERROR("Cannot initialize device base class.\n");
81 return NULL;
82 }
83
84 /* Get the index in the device version information table. */
85 version_idx =
86 me8200_versions_get_device_index(me8200_device->base.info.pci.
87 device_id);
88
89 // Initialize spin lock .
90 spin_lock_init(&me8200_device->irq_ctrl_lock);
91 spin_lock_init(&me8200_device->irq_mode_lock);
92 spin_lock_init(&me8200_device->dio_ctrl_lock);
93
94 /* Setup the PLX interrupt configuration */
95 outl(PLX_INTCSR_LOCAL_INT1_EN |
96 PLX_INTCSR_LOCAL_INT1_POL |
97 PLX_INTCSR_LOCAL_INT2_EN |
98 PLX_INTCSR_LOCAL_INT2_POL |
99 PLX_INTCSR_PCI_INT_EN,
100 me8200_device->base.info.pci.reg_bases[1] + PLX_INTCSR);
101
102 // Create subdevice instances.
103
104 for (i = 0; i < me8200_versions[version_idx].di_subdevices; i++) {
105 subdevice =
106 (me_subdevice_t *) me8200_di_constructor(me8200_device->
107 base.info.pci.
108 reg_bases[2], i,
109 me8200_device->
110 base.irq,
111 &me8200_device->
112 irq_ctrl_lock,
113 &me8200_device->
114 irq_mode_lock);
115
116 if (!subdevice) {
117 me_device_deinit((me_device_t *) me8200_device);
118 kfree(me8200_device);
119 PERROR("Cannot get memory for subdevice.\n");
120 return NULL;
121 }
122
123 me_slist_add_subdevice_tail(&me8200_device->base.slist,
124 subdevice);
125 }
126
127 for (i = 0; i < me8200_versions[version_idx].do_subdevices; i++) {
128 subdevice =
129 (me_subdevice_t *) me8200_do_constructor(me8200_device->
130 base.info.pci.
131 reg_bases[2], i,
132 me8200_device->
133 base.irq,
134 &me8200_device->
135 irq_mode_lock);
136
137 if (!subdevice) {
138 me_device_deinit((me_device_t *) me8200_device);
139 kfree(me8200_device);
140 PERROR("Cannot get memory for subdevice.\n");
141 return NULL;
142 }
143
144 me_slist_add_subdevice_tail(&me8200_device->base.slist,
145 subdevice);
146 }
147
148 for (i = 0; i < me8200_versions[version_idx].dio_subdevices; i++) {
149 subdevice =
150 (me_subdevice_t *) me8200_dio_constructor(me8200_device->
151 base.info.pci.
152 reg_bases[2], i,
153 &me8200_device->
154 dio_ctrl_lock);
155
156 if (!subdevice) {
157 me_device_deinit((me_device_t *) me8200_device);
158 kfree(me8200_device);
159 PERROR("Cannot get memory for subdevice.\n");
160 return NULL;
161 }
162
163 me_slist_add_subdevice_tail(&me8200_device->base.slist,
164 subdevice);
165 }
166
167 return (me_device_t *) me8200_device;
168}
169
170// Init and exit of module.
171
172static int __init me8200_init(void)
173{
174 PDEBUG("executed.\n.");
175 return 0;
176}
177
178static void __exit me8200_exit(void)
179{
180 PDEBUG("executed.\n.");
181}
182
183module_init(me8200_init);
184
185module_exit(me8200_exit);
186
187// Administrative stuff for modinfo.
188MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
189MODULE_DESCRIPTION("Device Driver Module for Template Device");
190MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
191MODULE_LICENSE("GPL");
192
193// Export the constructor.
194EXPORT_SYMBOL(me8200_pci_constructor);
diff --git a/drivers/staging/meilhaus/me8200_device.h b/drivers/staging/meilhaus/me8200_device.h
new file mode 100644
index 000000000000..cbd2a01ddb41
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_device.h
@@ -0,0 +1,97 @@
1/**
2 * @file me8200_device.h
3 *
4 * @brief ME-8200 device class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8200_DEVICE_H
28#define _ME8200_DEVICE_H
29
30#include <linux/pci.h>
31#include <linux/spinlock.h>
32
33#include "medevice.h"
34
35#ifdef __KERNEL__
36
37/**
38 * @brief Structure holding ME-8200 device capabilities.
39 */
40typedef struct me8200_version {
41 uint16_t device_id;
42 unsigned int di_subdevices;
43 unsigned int do_subdevices;
44 unsigned int dio_subdevices;
45} me8200_version_t;
46
47/**
48 * @brief Device capabilities.
49 */
50static me8200_version_t me8200_versions[] = {
51 {PCI_DEVICE_ID_MEILHAUS_ME8200_A, 1, 1, 2},
52 {PCI_DEVICE_ID_MEILHAUS_ME8200_B, 2, 2, 2},
53 {0},
54};
55
56#define ME8200_DEVICE_VERSIONS (sizeof(me8200_versions) / sizeof(me8200_version_t) - 1) /**< Returns the number of entries in #me8200_versions. */
57
58/**
59 * @brief Returns the index of the device entry in #me8200_versions.
60 *
61 * @param device_id The PCI device id of the device to query.
62 * @return The index of the device in #me8200_versions.
63 */
64static inline unsigned int me8200_versions_get_device_index(uint16_t device_id)
65{
66 unsigned int i;
67 for (i = 0; i < ME8200_DEVICE_VERSIONS; i++)
68 if (me8200_versions[i].device_id == device_id)
69 break;
70 return i;
71}
72
73/**
74 * @brief The ME-8200 device class structure.
75 */
76typedef struct me8200_device {
77 me_device_t base; /**< The Meilhaus device base class. */
78
79 /* Child class attributes. */
80 spinlock_t irq_ctrl_lock; /**< Lock for the interrupt control register. */
81 spinlock_t irq_mode_lock; /**< Lock for the interrupt mode register. */
82 spinlock_t dio_ctrl_lock; /**< Lock for the digital i/o control register. */
83} me8200_device_t;
84
85/**
86 * @brief The ME-8200 device class constructor.
87 *
88 * @param pci_device The pci device structure given by the PCI subsystem.
89 *
90 * @return On succes a new ME-8200 device instance. \n
91 * NULL on error.
92 */
93me_device_t *me8200_pci_constructor(struct pci_dev *pci_device)
94 __attribute__ ((weak));
95
96#endif
97#endif
diff --git a/drivers/staging/meilhaus/me8200_di.c b/drivers/staging/meilhaus/me8200_di.c
new file mode 100644
index 000000000000..0bb4567091cc
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_di.c
@@ -0,0 +1,857 @@
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 <asm/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
52static void me8200_di_destructor(struct me_subdevice *subdevice);
53static 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);
58static 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);
63static int me8200_di_io_irq_stop(me_subdevice_t * subdevice,
64 struct file *filep, int channel, int flags);
65static 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);
72static 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);
76static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
77 struct file *filep, int flags);
78static int me8200_di_query_number_channels(me_subdevice_t * subdevice,
79 int *number);
80static int me8200_di_query_subdevice_type(me_subdevice_t * subdevice,
81 int *type, int *subtype);
82static int me8200_di_query_subdevice_caps(me_subdevice_t * subdevice,
83 int *caps);
84#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
85static irqreturn_t me8200_isr(int irq, void *dev_id);
86#else
87static irqreturn_t me8200_isr(int irq, void *dev_id, struct pt_regs *regs);
88#endif
89#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
90static irqreturn_t me8200_isr_EX(int irq, void *dev_id);
91#else
92static irqreturn_t me8200_isr_EX(int irq, void *dev_id, struct pt_regs *regs);
93#endif
94static void me8200_di_check_version(me8200_di_subdevice_t * instance,
95 unsigned long addr);
96
97///Functions
98static int me8200_di_io_irq_start(me_subdevice_t * subdevice,
99 struct file *filep,
100 int channel,
101 int irq_source,
102 int irq_edge, int irq_arg, int flags)
103{
104 me8200_di_subdevice_t *instance;
105 int err = ME_ERRNO_SUCCESS;
106 volatile uint8_t tmp;
107 unsigned long status;
108
109 PDEBUG("executed.\n");
110
111 instance = (me8200_di_subdevice_t *) subdevice;
112
113 if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
114 if (flags &
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;
119 }
120
121 if (irq_edge != ME_IRQ_EDGE_NOT_USED) {
122 PERROR("Invalid irq edge specified.\n");
123 return ME_ERRNO_INVALID_IRQ_EDGE;
124 }
125 } else if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
126 if (flags &
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;
131 }
132
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;
138 }
139
140 if (!(irq_arg & 0xFF)) {
141 PERROR("No mask specified.\n");
142 return ME_ERRNO_INVALID_IRQ_ARG;
143 }
144 } else {
145 PERROR("Invalid irq source specified.\n");
146 return ME_ERRNO_INVALID_IRQ_SOURCE;
147 }
148
149 if (channel) {
150 PERROR("Invalid channel specified.\n");
151 return ME_ERRNO_INVALID_CHANNEL;
152 }
153
154 ME_SUBDEVICE_ENTER;
155
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",
160 instance->reg_base,
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",
164 instance->reg_base,
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;
169 }
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",
173 instance->reg_base,
174 instance->mask_reg - instance->reg_base, irq_arg);
175 instance->filtering_flag = 0;
176 }
177
178 spin_lock(instance->irq_mode_lock);
179 tmp = inb(instance->irq_mode_reg);
180 tmp &=
181 ~(ME8200_IRQ_MODE_MASK <<
182 (ME8200_IRQ_MODE_DI_SHIFT * instance->di_idx));
183 if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
184 tmp |=
185 ME8200_IRQ_MODE_MASK_COMPARE << (ME8200_IRQ_MODE_DI_SHIFT *
186 instance->di_idx);
187 }
188
189 if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
190 tmp |=
191 ME8200_IRQ_MODE_MASK_MASK << (ME8200_IRQ_MODE_DI_SHIFT *
192 instance->di_idx);
193 }
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);
198
199 spin_lock(instance->irq_ctrl_lock);
200 tmp = inb(instance->irq_ctrl_reg);
201 tmp |=
202 (ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
203 (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
204 tmp |=
205 ME8200_DI_IRQ_CTRL_BIT_ENABLE << (ME8200_DI_IRQ_CTRL_SHIFT *
206 instance->di_idx);
207
208 if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
209 tmp &=
210 ~(ME8200_DI_IRQ_CTRL_MASK_EDGE <<
211 (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
212 if (irq_edge == ME_IRQ_EDGE_RISING) {
213 tmp |=
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) {
217 tmp |=
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) {
221 tmp |=
222 ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY <<
223 (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx);
224 }
225 }
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);
229 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);
235
236 instance->line_value = inb(instance->port_reg);
237 spin_unlock(instance->irq_ctrl_lock);
238
239 instance->rised = 0;
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);
244 ME_SUBDEVICE_EXIT;
245
246 return err;
247}
248
249static int me8200_di_io_irq_wait(me_subdevice_t * subdevice,
250 struct file *filep,
251 int channel,
252 int *irq_count,
253 int *value, int time_out, int flags)
254{
255 me8200_di_subdevice_t *instance;
256 int err = ME_ERRNO_SUCCESS;
257 long t = 0;
258 unsigned long cpu_flags;
259 int count;
260
261 PDEBUG("executed.\n");
262 PDEVELOP("PID: %d.\n", current->pid);
263
264 instance = (me8200_di_subdevice_t *) subdevice;
265
266 if (flags &
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;
270 }
271
272 if (channel) {
273 PERROR("Invalid channel specified.\n");
274 return ME_ERRNO_INVALID_CHANNEL;
275 }
276
277 if (time_out < 0) {
278 PERROR("Invalid time_out specified.\n");
279 return ME_ERRNO_INVALID_TIMEOUT;
280 }
281
282 if (time_out) {
283 t = (time_out * HZ) / 1000;
284
285 if (t == 0)
286 t = 1;
287 }
288
289 ME_SUBDEVICE_ENTER;
290
291 if (instance->rised <= 0) {
292 instance->rised = 0;
293 count = instance->count;
294
295 if (time_out) {
296 t = wait_event_interruptible_timeout(instance->
297 wait_queue,
298 ((count !=
299 instance->count)
300 || (instance->
301 rised < 0)),
302 t);
303// t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t);
304 if (t == 0) {
305 PERROR("Wait on interrupt timed out.\n");
306 err = ME_ERRNO_TIMEOUT;
307 }
308 } else {
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));
313 }
314
315 if (instance->rised < 0) {
316 PERROR("Wait on interrupt aborted by user.\n");
317 err = ME_ERRNO_CANCELLED;
318 }
319 }
320
321 if (signal_pending(current)) {
322 PERROR("Wait on interrupt aborted by signal.\n");
323 err = ME_ERRNO_SIGNAL;
324 }
325
326 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
327 *irq_count = instance->count;
328 if (!err) {
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;
336 } else {
337 *value = instance->status_value_edges;
338 }
339 }
340 instance->rised = 0;
341/*
342 instance->status_value = 0;
343 instance->status_value_edges = 0;
344*/
345 } else {
346 *value = 0;
347 }
348 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
349
350 ME_SUBDEVICE_EXIT;
351
352 return err;
353}
354
355static int me8200_di_io_irq_stop(me_subdevice_t * subdevice,
356 struct file *filep, int channel, int flags)
357{
358 me8200_di_subdevice_t *instance;
359 uint8_t tmp;
360 unsigned long status;
361
362 PDEBUG("executed.\n");
363
364 instance = (me8200_di_subdevice_t *) subdevice;
365
366 if (flags) {
367 PERROR("Invalid flag specified.\n");
368 return ME_ERRNO_INVALID_FLAGS;
369 }
370
371 if (channel) {
372 PERROR("Invalid channel specified.\n");
373 return ME_ERRNO_INVALID_CHANNEL;
374 }
375
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);
379 tmp |=
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);
385 tmp &=
386 ~(ME8200_DI_IRQ_CTRL_BIT_ENABLE <<
387 (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
388 tmp |=
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);
396
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);
403
404 ME_SUBDEVICE_EXIT;
405
406 return ME_ERRNO_SUCCESS;
407}
408
409static int me8200_di_io_single_config(me_subdevice_t * subdevice,
410 struct file *filep,
411 int channel,
412 int single_config,
413 int ref,
414 int trig_chan,
415 int trig_type, int trig_edge, int flags)
416{
417 me8200_di_subdevice_t *instance;
418 int err = ME_ERRNO_SUCCESS;
419 unsigned long status;
420
421 PDEBUG("executed.\n");
422
423 instance = (me8200_di_subdevice_t *) subdevice;
424
425 ME_SUBDEVICE_ENTER;
426
427 spin_lock_irqsave(&instance->subdevice_lock, status);
428
429 switch (flags) {
430 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
431 case ME_IO_SINGLE_CONFIG_DIO_BYTE:
432 if (channel == 0) {
433 if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
434 } else {
435 PERROR("Invalid port direction specified.\n");
436 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
437 }
438 } else {
439 PERROR("Invalid channel number.\n");
440 err = ME_ERRNO_INVALID_CHANNEL;
441 }
442 break;
443
444 default:
445 PERROR("Invalid flags specified.\n");
446 err = ME_ERRNO_INVALID_FLAGS;
447 }
448
449 spin_unlock_irqrestore(&instance->subdevice_lock, status);
450
451 ME_SUBDEVICE_EXIT;
452
453 return err;
454}
455
456static int me8200_di_io_single_read(me_subdevice_t * subdevice,
457 struct file *filep,
458 int channel,
459 int *value, int time_out, int flags)
460{
461 me8200_di_subdevice_t *instance;
462 int err = ME_ERRNO_SUCCESS;
463 unsigned long status;
464
465 PDEBUG("executed.\n");
466
467 instance = (me8200_di_subdevice_t *) subdevice;
468
469 ME_SUBDEVICE_ENTER;
470
471 spin_lock_irqsave(&instance->subdevice_lock, status);
472
473 switch (flags) {
474 case ME_IO_SINGLE_TYPE_DIO_BIT:
475 if ((channel >= 0) && (channel < 8)) {
476 *value = inb(instance->port_reg) & (0x1 << channel);
477 } else {
478 PERROR("Invalid bit number specified.\n");
479 err = ME_ERRNO_INVALID_CHANNEL;
480 }
481 break;
482
483 case ME_IO_SINGLE_NO_FLAGS:
484 case ME_IO_SINGLE_TYPE_DIO_BYTE:
485 if (channel == 0) {
486 *value = inb(instance->port_reg);
487 } else {
488 PERROR("Invalid channel number.\n");
489 err = ME_ERRNO_INVALID_CHANNEL;
490 }
491 break;
492
493 default:
494 PERROR("Invalid flags specified.\n");
495 err = ME_ERRNO_INVALID_FLAGS;
496 }
497
498 spin_unlock_irqrestore(&instance->subdevice_lock, status);
499
500 ME_SUBDEVICE_EXIT;
501
502 return err;
503}
504
505static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
506 struct file *filep, int flags)
507{
508 me8200_di_subdevice_t *instance = (me8200_di_subdevice_t *) subdevice;
509
510 PDEBUG("executed.\n");
511
512 if (flags) {
513 PERROR("Invalid flag specified.\n");
514 return ME_ERRNO_INVALID_FLAGS;
515 }
516
517 instance->count = 0;
518 return me8200_di_io_irq_stop(subdevice, filep, 0, 0);
519}
520
521static int me8200_di_query_number_channels(me_subdevice_t * subdevice,
522 int *number)
523{
524 PDEBUG("executed.\n");
525 *number = 8;
526 return ME_ERRNO_SUCCESS;
527}
528
529static int me8200_di_query_subdevice_type(me_subdevice_t * subdevice,
530 int *type, int *subtype)
531{
532 PDEBUG("executed.\n");
533 *type = ME_TYPE_DI;
534 *subtype = ME_SUBTYPE_SINGLE;
535 return ME_ERRNO_SUCCESS;
536}
537
538static int me8200_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
539{
540 PDEBUG("executed.\n");
541 *caps =
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;
547}
548
549#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
550static irqreturn_t me8200_isr(int irq, void *dev_id)
551#else
552static irqreturn_t me8200_isr(int irq, void *dev_id, struct pt_regs *regs)
553#endif
554{
555 me8200_di_subdevice_t *instance;
556 uint8_t ctrl;
557 uint8_t irq_status;
558 uint8_t line_value = 0;
559 uint8_t line_status = 0;
560 uint32_t status_val = 0;
561
562 instance = (me8200_di_subdevice_t *) dev_id;
563
564 if (irq != instance->irq) {
565 PERROR("Incorrect interrupt num: %d.\n", irq);
566 return IRQ_NONE;
567 }
568
569 irq_status = inb(instance->irq_status_reg);
570 if (!irq_status) {
571 PINFO
572 ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
573 jiffies, __FUNCTION__, instance->di_idx, irq_status);
574 return IRQ_NONE;
575 }
576
577 PDEBUG("executed.\n");
578
579 spin_lock(&instance->subdevice_lock);
580 spin_lock(instance->irq_ctrl_lock);
581 ctrl = inb(instance->irq_ctrl_reg);
582 ctrl |=
583 ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT *
584 instance->di_idx);
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);
588 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);
594
595 line_value = inb(instance->port_reg);
596 spin_unlock(instance->irq_ctrl_lock);
597
598 line_status = ((uint8_t) instance->line_value ^ line_value);
599
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
603
604 instance->line_value = (int)line_value;
605
606 if (instance->rised == 0) {
607 instance->status_value = irq_status | line_status;
608 instance->status_value_edges = status_val;
609 } else {
610 instance->status_value |= irq_status | line_status;
611 instance->status_value_edges |= status_val;
612 }
613
614 if (instance->filtering_flag) { // For compare mode only.
615 if (instance->compare_value == instance->line_value) {
616 instance->rised = 1;
617 instance->count++;
618 }
619 } else {
620 instance->rised = 1;
621 instance->count++;
622 }
623 spin_unlock(&instance->subdevice_lock);
624
625 spin_unlock(&instance->subdevice_lock);
626
627 wake_up_interruptible_all(&instance->wait_queue);
628
629 return IRQ_HANDLED;
630}
631
632#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
633static irqreturn_t me8200_isr_EX(int irq, void *dev_id)
634#else
635static irqreturn_t me8200_isr_EX(int irq, void *dev_id, struct pt_regs *regs)
636#endif
637{
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;
642 int i, j;
643
644 instance = (me8200_di_subdevice_t *) dev_id;
645
646 if (irq != instance->irq) {
647 PERROR("Incorrect interrupt num: %d.\n", irq);
648 return IRQ_NONE;
649 }
650
651 PDEBUG("executed.\n");
652
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,
656 irq_status);
657
658 if (!irq_status) {
659 PINFO
660 ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
661 jiffies, __FUNCTION__, instance->di_idx, irq_status);
662 return IRQ_NONE;
663 }
664
665 irq_status_EX = inb(instance->irq_status_low_reg);
666 irq_status_EX |= (inb(instance->irq_status_high_reg) << 8);
667
668 PDEVELOP("EXTENDED REG: 0x%04x\n", irq_status_EX);
669 instance->line_value = inb(instance->port_reg);
670
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
675 }
676
677 spin_lock(&instance->subdevice_lock);
678 if (instance->rised == 0) {
679 instance->status_value = irq_status;
680 instance->status_value_edges = status_val;
681 } else {
682 instance->status_value |= irq_status;
683 instance->status_value_edges |= status_val;
684 }
685
686 if (instance->filtering_flag) { // For compare mode only.
687 if (instance->compare_value == instance->line_value) {
688 instance->rised = 1;
689 instance->count++;
690 }
691 } else {
692 instance->rised = 1;
693 instance->count++;
694 }
695 spin_unlock(&instance->subdevice_lock);
696
697 wake_up_interruptible_all(&instance->wait_queue);
698
699 return IRQ_HANDLED;
700}
701
702static void me8200_di_destructor(struct me_subdevice *subdevice)
703{
704 me8200_di_subdevice_t *instance;
705
706 PDEBUG("executed.\n");
707
708 instance = (me8200_di_subdevice_t *) subdevice;
709
710 free_irq(instance->irq, (void *)instance);
711 me_subdevice_deinit(&instance->base);
712 kfree(instance);
713}
714
715me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_regbase,
716 unsigned int di_idx,
717 int irq,
718 spinlock_t * irq_ctrl_lock,
719 spinlock_t * irq_mode_lock)
720{
721 me8200_di_subdevice_t *subdevice;
722 int err;
723
724 PDEBUG("executed.\n");
725
726 /* Allocate memory for subdevice instance */
727 subdevice = kmalloc(sizeof(me8200_di_subdevice_t), GFP_KERNEL);
728
729 if (!subdevice) {
730 PERROR("Cannot get memory for subdevice instance.\n");
731 return NULL;
732 }
733
734 memset(subdevice, 0, sizeof(me8200_di_subdevice_t));
735
736 /* Initialize subdevice base class */
737 err = me_subdevice_init(&subdevice->base);
738
739 if (err) {
740 PERROR("Cannot initialize subdevice base class instance.\n");
741 kfree(subdevice);
742 return NULL;
743 }
744 // Check firmware version.
745 me8200_di_check_version(subdevice,
746 me8200_regbase + ME8200_FIRMWARE_VERSION_REG);
747
748 // Initialize spin locks.
749 spin_lock_init(&subdevice->subdevice_lock);
750
751 subdevice->irq_ctrl_lock = irq_ctrl_lock;
752 subdevice->irq_mode_lock = irq_mode_lock;
753
754 /* Save the subdevice index. */
755 subdevice->di_idx = di_idx;
756
757 /* Initialize registers */
758 if (di_idx == 0) {
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;
765
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;
777
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;
782 } else {
783 PERROR("Wrong subdevice idx=%d.\n", di_idx);
784 kfree(subdevice);
785 return NULL;
786 }
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;
791#endif
792
793 /* Initialize wait queue */
794 init_waitqueue_head(&subdevice->wait_queue);
795
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;
812
813 subdevice->rised = 0;
814 subdevice->count = 0;
815
816 /* Register interrupt service routine. */
817 subdevice->irq = irq;
818 if (subdevice->version > 0) { // NEW
819 err = request_irq(subdevice->irq, me8200_isr_EX,
820#ifdef IRQF_DISABLED
821 IRQF_DISABLED | IRQF_SHARED,
822#else
823 SA_INTERRUPT | SA_SHIRQ,
824#endif
825 ME8200_NAME, (void *)subdevice);
826 } else { //OLD
827 err = request_irq(subdevice->irq, me8200_isr,
828#ifdef IRQF_DISABLED
829 IRQF_DISABLED | IRQF_SHARED,
830#else
831 SA_INTERRUPT | SA_SHIRQ,
832#endif
833 ME8200_NAME, (void *)subdevice);
834 }
835
836 if (err) {
837 PERROR("Cannot initialize subdevice base class instance.\n");
838 kfree(subdevice);
839 return NULL;
840 }
841 PDEBUG("Registred irq=%d.\n", subdevice->irq);
842
843 return subdevice;
844}
845
846static void me8200_di_check_version(me8200_di_subdevice_t * instance,
847 unsigned long addr)
848{
849
850 PDEBUG("executed.\n");
851 instance->version = 0x000000FF & inb(addr);
852 PDEVELOP("me8200 firmware version: %d\n", instance->version);
853
854 /// @note Fix for wrong values in this registry.
855 if ((instance->version < 0x7) || (instance->version > 0x1F))
856 instance->version = 0x0;
857}
diff --git a/drivers/staging/meilhaus/me8200_di.h b/drivers/staging/meilhaus/me8200_di.h
new file mode 100644
index 000000000000..2a3b005b67d4
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_di.h
@@ -0,0 +1,92 @@
1/**
2 * @file me8200_di.h
3 *
4 * @brief ME-8200 digital input subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8200_DI_H_
28#define _ME8200_DI_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me8200_di_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock;
44 spinlock_t *irq_ctrl_lock;
45 spinlock_t *irq_mode_lock;
46
47 unsigned int di_idx;
48 unsigned int version;
49
50 int irq; /**< The number of the interrupt request. */
51 volatile int rised; /**< Flag to indicate if an interrupt occured. */
52 uint status_flag; /**< Default interupt status flag */
53 uint status_value; /**< Interupt status */
54 uint status_value_edges; /**< Extended interupt status */
55 uint line_value;
56 int count; /**< Counts the number of interrupts occured. */
57 uint8_t compare_value;
58 uint8_t filtering_flag;
59
60 wait_queue_head_t wait_queue; /**< To wait on interrupts. */
61
62 unsigned long port_reg; /**< The digital input port. */
63 unsigned long compare_reg; /**< The register to hold the value to compare with. */
64 unsigned long mask_reg; /**< The register to hold the mask. */
65 unsigned long irq_mode_reg; /**< The interrupt mode register. */
66 unsigned long irq_ctrl_reg; /**< The interrupt control register. */
67 unsigned long irq_status_reg; /**< The interrupt status register. Also interrupt reseting register (firmware version 7 and later).*/
68#ifdef MEDEBUG_DEBUG_REG
69 unsigned long reg_base;
70#endif
71 unsigned long firmware_version_reg; /**< The interrupt reseting register. */
72
73 unsigned long irq_status_low_reg; /**< The interrupt extended status register (low part). */
74 unsigned long irq_status_high_reg; /**< The interrupt extended status register (high part). */
75} me8200_di_subdevice_t;
76
77/**
78 * @brief The constructor to generate a ME-8200 digital input subdevice instance.
79 *
80 * @param reg_base The register base address of the device as returned by the PCI BIOS.
81 *
82 * @return Pointer to new instance on success.\n
83 * NULL on error.
84 */
85me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_reg_base,
86 unsigned int di_idx,
87 int irq,
88 spinlock_t * irq_ctrl_lock,
89 spinlock_t * irq_mode_lock);
90
91#endif
92#endif
diff --git a/drivers/staging/meilhaus/me8200_di_reg.h b/drivers/staging/meilhaus/me8200_di_reg.h
new file mode 100644
index 000000000000..b9a619d31c2c
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_di_reg.h
@@ -0,0 +1,75 @@
1/**
2 * @file me8200_di_reg.h
3 *
4 * @brief ME-8200 digital input subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8200_DI_REG_H_
28#define _ME8200_DI_REG_H_
29
30#ifdef __KERNEL__
31
32// Common registry for whole family.
33#define ME8200_DI_PORT_0_REG 0x3 // R
34#define ME8200_DI_PORT_1_REG 0x4 // R
35
36#define ME8200_DI_MASK_0_REG 0x5 // R/W
37#define ME8200_DI_MASK_1_REG 0x6 // R/W
38
39#define ME8200_DI_COMPARE_0_REG 0xA // R/W
40#define ME8200_DI_COMPARE_1_REG 0xB // R/W
41
42#define ME8200_DI_IRQ_CTRL_REG 0xC // R/W
43
44#ifndef ME8200_IRQ_MODE_REG
45# define ME8200_IRQ_MODE_REG 0xD // R/W
46#endif
47
48// This registry are for all versions
49#define ME8200_DI_CHANGE_0_REG 0xE // R
50#define ME8200_DI_CHANGE_1_REG 0xF // R
51
52#define ME8200_DI_IRQ_CTRL_BIT_CLEAR 0x4
53#define ME8200_DI_IRQ_CTRL_BIT_ENABLE 0x8
54
55// This registry are for firmware versions 7 and later
56#define ME8200_DI_EXTEND_CHANGE_0_LOW_REG 0x10 // R
57#define ME8200_DI_EXTEND_CHANGE_0_HIGH_REG 0x11 // R
58#define ME8200_DI_EXTEND_CHANGE_1_LOW_REG 0x12 // R
59#define ME8200_DI_EXTEND_CHANGE_1_HIGH_REG 0x13 // R
60
61#ifndef ME8200_FIRMWARE_VERSION_REG
62# define ME8200_FIRMWARE_VERSION_REG 0x14 // R
63#endif
64
65// Bit definitions
66#define ME8200_DI_IRQ_CTRL_MASK_EDGE 0x3
67#define ME8200_DI_IRQ_CTRL_MASK_EDGE_RISING 0x0
68#define ME8200_DI_IRQ_CTRL_MASK_EDGE_FALLING 0x1
69#define ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY 0x3
70
71// Others
72#define ME8200_DI_IRQ_CTRL_SHIFT 4
73
74#endif
75#endif
diff --git a/drivers/staging/meilhaus/me8200_dio.c b/drivers/staging/meilhaus/me8200_dio.c
new file mode 100644
index 000000000000..ff8ca1b8b7f3
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_dio.c
@@ -0,0 +1,418 @@
1/**
2 * @file me8200_dio.c
3 *
4 * @brief ME-8200 digital input/output 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
42#include "medefines.h"
43#include "meinternal.h"
44#include "meerror.h"
45
46#include "medebug.h"
47#include "me8200_dio_reg.h"
48#include "me8200_dio.h"
49
50/*
51 * Defines
52 */
53
54/*
55 * Functions
56 */
57
58static int me8200_dio_io_reset_subdevice(struct me_subdevice *subdevice,
59 struct file *filep, int flags)
60{
61 me8200_dio_subdevice_t *instance;
62 uint8_t mode;
63
64 PDEBUG("executed.\n");
65
66 if (flags) {
67 PERROR("Invalid flag specified.\n");
68 return ME_ERRNO_INVALID_FLAGS;
69 }
70
71 instance = (me8200_dio_subdevice_t *) subdevice;
72
73 ME_SUBDEVICE_ENTER;
74
75 spin_lock(&instance->subdevice_lock);
76 spin_lock(instance->ctrl_reg_lock);
77 mode = inb(instance->ctrl_reg);
78 mode &= ~(0x3 << (instance->dio_idx * 2));
79 outb(mode, instance->ctrl_reg);
80 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
81 instance->ctrl_reg - instance->reg_base, mode);
82 spin_unlock(instance->ctrl_reg_lock);
83 outb(0x00, instance->port_reg);
84 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
85 instance->port_reg - instance->reg_base, 0x00);
86 spin_unlock(&instance->subdevice_lock);
87
88 ME_SUBDEVICE_EXIT;
89
90 return ME_ERRNO_SUCCESS;
91}
92
93static int me8200_dio_io_single_config(me_subdevice_t * subdevice,
94 struct file *filep,
95 int channel,
96 int single_config,
97 int ref,
98 int trig_chan,
99 int trig_type, int trig_edge, int flags)
100{
101 me8200_dio_subdevice_t *instance;
102 int err = ME_ERRNO_SUCCESS;
103 uint32_t mode;
104 uint32_t size =
105 flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
106 | ME_IO_SINGLE_CONFIG_DIO_WORD |
107 ME_IO_SINGLE_CONFIG_DIO_DWORD);
108
109 PDEBUG("executed.\n");
110
111 instance = (me8200_dio_subdevice_t *) subdevice;
112
113 ME_SUBDEVICE_ENTER;
114
115 spin_lock(&instance->subdevice_lock);
116 spin_lock(instance->ctrl_reg_lock);
117 mode = inb(instance->ctrl_reg);
118 switch (size) {
119 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
120 case ME_IO_SINGLE_CONFIG_DIO_BYTE:
121 if (channel == 0) {
122 if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
123 mode &=
124 ~((ME8200_DIO_CTRL_BIT_MODE_0 |
125 ME8200_DIO_CTRL_BIT_MODE_1) <<
126 (instance->dio_idx * 2));
127 } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
128 mode &=
129 ~((ME8200_DIO_CTRL_BIT_MODE_0 |
130 ME8200_DIO_CTRL_BIT_MODE_1) <<
131 (instance->dio_idx * 2));
132 mode |=
133 ME8200_DIO_CTRL_BIT_MODE_0 << (instance->
134 dio_idx * 2);
135 } else {
136 PERROR
137 ("Invalid port configuration specified.\n");
138 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
139 }
140 } else {
141 PERROR("Invalid channel number.\n");
142 err = ME_ERRNO_INVALID_CHANNEL;
143 }
144
145 break;
146
147 default:
148 PERROR("Invalid flags.\n");
149
150 err = ME_ERRNO_INVALID_FLAGS;
151 }
152
153 if (!err) {
154 outb(mode, instance->ctrl_reg);
155 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
156 instance->reg_base,
157 instance->ctrl_reg - instance->reg_base, mode);
158 }
159 spin_unlock(instance->ctrl_reg_lock);
160 spin_unlock(&instance->subdevice_lock);
161
162 ME_SUBDEVICE_EXIT;
163
164 return err;
165}
166
167static int me8200_dio_io_single_read(me_subdevice_t * subdevice,
168 struct file *filep,
169 int channel,
170 int *value, int time_out, int flags)
171{
172 me8200_dio_subdevice_t *instance;
173 int err = ME_ERRNO_SUCCESS;
174 uint8_t mode;
175
176 PDEBUG("executed.\n");
177
178 instance = (me8200_dio_subdevice_t *) subdevice;
179
180 ME_SUBDEVICE_ENTER;
181
182 spin_lock(&instance->subdevice_lock);
183 spin_lock(instance->ctrl_reg_lock);
184 switch (flags) {
185 case ME_IO_SINGLE_TYPE_DIO_BIT:
186 if ((channel >= 0) && (channel < 8)) {
187 mode =
188 inb(instance->
189 ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
190 ME8200_DIO_CTRL_BIT_MODE_1) <<
191 (instance->dio_idx * 2));
192
193 if ((mode ==
194 (ME8200_DIO_CTRL_BIT_MODE_0 <<
195 (instance->dio_idx * 2))) || !mode) {
196 *value =
197 inb(instance->
198 port_reg) & (0x0001 << channel);
199 } else {
200 PERROR("Port not in output or input mode.\n");
201 err = ME_ERRNO_PREVIOUS_CONFIG;
202 }
203 } else {
204 PERROR("Invalid bit number specified.\n");
205 err = ME_ERRNO_INVALID_CHANNEL;
206 }
207 break;
208
209 case ME_IO_SINGLE_NO_FLAGS:
210 case ME_IO_SINGLE_TYPE_DIO_BYTE:
211 if (channel == 0) {
212 mode =
213 inb(instance->
214 ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
215 ME8200_DIO_CTRL_BIT_MODE_1) <<
216 (instance->dio_idx * 2));
217
218 if ((mode ==
219 (ME8200_DIO_CTRL_BIT_MODE_0 <<
220 (instance->dio_idx * 2))) || !mode) {
221 *value = inb(instance->port_reg) & 0x00FF;
222 } else {
223 PERROR("Port not in output or input mode.\n");
224 err = ME_ERRNO_PREVIOUS_CONFIG;
225 }
226 } else {
227 PERROR("Invalid byte number specified.\n");
228 err = ME_ERRNO_INVALID_CHANNEL;
229 }
230 break;
231
232 default:
233 PERROR("Invalid flags specified.\n");
234 err = ME_ERRNO_INVALID_FLAGS;
235 }
236 spin_unlock(instance->ctrl_reg_lock);
237 spin_unlock(&instance->subdevice_lock);
238
239 ME_SUBDEVICE_EXIT;
240
241 return err;
242}
243
244static int me8200_dio_io_single_write(me_subdevice_t * subdevice,
245 struct file *filep,
246 int channel,
247 int value, int time_out, int flags)
248{
249 me8200_dio_subdevice_t *instance;
250 int err = ME_ERRNO_SUCCESS;
251 uint8_t mode;
252 uint8_t byte;
253
254 PDEBUG("executed.\n");
255
256 instance = (me8200_dio_subdevice_t *) subdevice;
257
258 ME_SUBDEVICE_ENTER;
259
260 spin_lock(&instance->subdevice_lock);
261 spin_lock(instance->ctrl_reg_lock);
262 switch (flags) {
263 case ME_IO_SINGLE_TYPE_DIO_BIT:
264 if ((channel >= 0) && (channel < 8)) {
265 mode =
266 inb(instance->
267 ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
268 ME8200_DIO_CTRL_BIT_MODE_1) <<
269 (instance->dio_idx * 2));
270
271 if (mode ==
272 (ME8200_DIO_CTRL_BIT_MODE_0 <<
273 (instance->dio_idx * 2))) {
274 byte = inb(instance->port_reg);
275
276 if (value)
277 byte |= 0x1 << channel;
278 else
279 byte &= ~(0x1 << channel);
280
281 outb(byte, instance->port_reg);
282 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
283 instance->reg_base,
284 instance->port_reg -
285 instance->reg_base, byte);
286 } else {
287 PERROR("Port not in output or input mode.\n");
288 err = ME_ERRNO_PREVIOUS_CONFIG;
289 }
290 } else {
291 PERROR("Invalid bit number specified.\n");
292 err = ME_ERRNO_INVALID_CHANNEL;
293 }
294 break;
295
296 case ME_IO_SINGLE_NO_FLAGS:
297 case ME_IO_SINGLE_TYPE_DIO_BYTE:
298 if (channel == 0) {
299 mode =
300 inb(instance->
301 ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
302 ME8200_DIO_CTRL_BIT_MODE_1) <<
303 (instance->dio_idx * 2));
304
305 if (mode ==
306 (ME8200_DIO_CTRL_BIT_MODE_0 <<
307 (instance->dio_idx * 2))) {
308 outb(value, instance->port_reg);
309 PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
310 instance->reg_base,
311 instance->port_reg -
312 instance->reg_base, value);
313 } else {
314 PERROR("Port not in output or input mode.\n");
315 err = ME_ERRNO_PREVIOUS_CONFIG;
316 }
317 } else {
318 PERROR("Invalid byte number specified.\n");
319 err = ME_ERRNO_INVALID_CHANNEL;
320 }
321 break;
322
323 default:
324 PERROR("Invalid flags specified.\n");
325 err = ME_ERRNO_INVALID_FLAGS;
326 }
327 spin_unlock(instance->ctrl_reg_lock);
328 spin_unlock(&instance->subdevice_lock);
329
330 ME_SUBDEVICE_EXIT;
331
332 return err;
333}
334
335static int me8200_dio_query_number_channels(me_subdevice_t * subdevice,
336 int *number)
337{
338 PDEBUG("executed.\n");
339 *number = 8;
340 return ME_ERRNO_SUCCESS;
341}
342
343static int me8200_dio_query_subdevice_type(me_subdevice_t * subdevice,
344 int *type, int *subtype)
345{
346 PDEBUG("executed.\n");
347 *type = ME_TYPE_DIO;
348 *subtype = ME_SUBTYPE_SINGLE;
349 return ME_ERRNO_SUCCESS;
350}
351
352static int me8200_dio_query_subdevice_caps(me_subdevice_t * subdevice,
353 int *caps)
354{
355 PDEBUG("executed.\n");
356 *caps = ME_CAPS_DIO_DIR_BYTE;
357 return ME_ERRNO_SUCCESS;
358}
359
360me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base,
361 unsigned int dio_idx,
362 spinlock_t * ctrl_reg_lock)
363{
364 me8200_dio_subdevice_t *subdevice;
365 int err;
366
367 PDEBUG("executed.\n");
368
369 /* Allocate memory for subdevice instance */
370 subdevice = kmalloc(sizeof(me8200_dio_subdevice_t), GFP_KERNEL);
371
372 if (!subdevice) {
373 PERROR("Cannot get memory for subdevice instance.\n");
374 return NULL;
375 }
376
377 memset(subdevice, 0, sizeof(me8200_dio_subdevice_t));
378
379 /* Initialize subdevice base class */
380 err = me_subdevice_init(&subdevice->base);
381
382 if (err) {
383 PERROR("Cannot initialize subdevice base class instance.\n");
384 kfree(subdevice);
385 return NULL;
386 }
387 // Initialize spin locks.
388 spin_lock_init(&subdevice->subdevice_lock);
389
390 subdevice->ctrl_reg_lock = ctrl_reg_lock;
391
392 /* Save digital i/o index */
393 subdevice->dio_idx = dio_idx;
394
395 /* Save the subdevice index */
396 subdevice->ctrl_reg = reg_base + ME8200_DIO_CTRL_REG;
397 subdevice->port_reg = reg_base + ME8200_DIO_PORT_REG + dio_idx;
398#ifdef MEDEBUG_DEBUG_REG
399 subdevice->reg_base = reg_base;
400#endif
401
402 /* Overload base class methods. */
403 subdevice->base.me_subdevice_io_reset_subdevice =
404 me8200_dio_io_reset_subdevice;
405 subdevice->base.me_subdevice_io_single_config =
406 me8200_dio_io_single_config;
407 subdevice->base.me_subdevice_io_single_read = me8200_dio_io_single_read;
408 subdevice->base.me_subdevice_io_single_write =
409 me8200_dio_io_single_write;
410 subdevice->base.me_subdevice_query_number_channels =
411 me8200_dio_query_number_channels;
412 subdevice->base.me_subdevice_query_subdevice_type =
413 me8200_dio_query_subdevice_type;
414 subdevice->base.me_subdevice_query_subdevice_caps =
415 me8200_dio_query_subdevice_caps;
416
417 return subdevice;
418}
diff --git a/drivers/staging/meilhaus/me8200_dio.h b/drivers/staging/meilhaus/me8200_dio.h
new file mode 100644
index 000000000000..9ddd93d26f15
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_dio.h
@@ -0,0 +1,68 @@
1/**
2 * @file me8200_dio.h
3 *
4 * @brief ME-8200 digital input/output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8200_DIO_H_
28#define _ME8200_DIO_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me8200_dio_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
44 unsigned int dio_idx; /**< The index of the digital i/o on the device. */
45
46 unsigned long port_reg; /**< Register holding the port status. */
47 unsigned long ctrl_reg; /**< Register to configure the port direction. */
48#ifdef MEDEBUG_DEBUG_REG
49 unsigned long reg_base;
50#endif
51} me8200_dio_subdevice_t;
52
53/**
54 * @brief The constructor to generate a ME-8200 digital input/ouput subdevice instance.
55 *
56 * @param reg_base The register base address of the device as returned by the PCI BIOS.
57 * @param dio_idx The index of the digital i/o port on the device.
58 * @param ctrl_reg_lock Spin lock protecting the control register.
59 *
60 * @return Pointer to new instance on success.\n
61 * NULL on error.
62 */
63me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base,
64 unsigned int dio_idx,
65 spinlock_t * ctrl_reg_lock);
66
67#endif
68#endif
diff --git a/drivers/staging/meilhaus/me8200_dio_reg.h b/drivers/staging/meilhaus/me8200_dio_reg.h
new file mode 100644
index 000000000000..ac94a133abaf
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_dio_reg.h
@@ -0,0 +1,43 @@
1/**
2 * @file me8200_dio_reg.h
3 *
4 * @brief ME-8200 digital input/output subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8200_DIO_REG_H_
28#define _ME8200_DIO_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME8200_DIO_CTRL_REG 0x7 // R/W
33#define ME8200_DIO_PORT_0_REG 0x8 // R/W
34#define ME8200_DIO_PORT_1_REG 0x9 // R/W
35#define ME8200_DIO_PORT_REG ME8200_DIO_PORT_0_REG // R/W
36
37#define ME8200_DIO_CTRL_BIT_MODE_0 0x01
38#define ME8200_DIO_CTRL_BIT_MODE_1 0x02
39#define ME8200_DIO_CTRL_BIT_MODE_2 0x04
40#define ME8200_DIO_CTRL_BIT_MODE_3 0x08
41
42#endif
43#endif
diff --git a/drivers/staging/meilhaus/me8200_do.c b/drivers/staging/meilhaus/me8200_do.c
new file mode 100644
index 000000000000..5f4ba5dfa860
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_do.c
@@ -0,0 +1,600 @@
1/**
2 * @file me8200_do.c
3 *
4 * @brief ME-8200 digital output 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 <linux/interrupt.h>
40#include <asm/io.h>
41#include <linux/types.h>
42#include <linux/version.h>
43
44#include "medefines.h"
45#include "meinternal.h"
46#include "meerror.h"
47
48#include "meids.h"
49#include "medebug.h"
50#include "me8200_reg.h"
51#include "me8200_do_reg.h"
52#include "me8200_do.h"
53
54/*
55 * Defines
56 */
57
58/*
59 * Functions
60 */
61
62static int me8200_do_io_irq_start(me_subdevice_t * subdevice,
63 struct file *filep,
64 int channel,
65 int irq_source,
66 int irq_edge, int irq_arg, int flags)
67{
68 me8200_do_subdevice_t *instance;
69 int err = ME_ERRNO_SUCCESS;
70 uint8_t tmp;
71 unsigned long status;
72
73 if (flags & ~ME_IO_IRQ_START_DIO_BYTE) {
74 PERROR("Invalid flag specified.\n");
75 return ME_ERRNO_INVALID_FLAGS;
76 }
77
78 if (channel != 0) {
79 PERROR("Invalid channel specified.\n");
80 return ME_ERRNO_INVALID_CHANNEL;
81 }
82
83 if (irq_source != ME_IRQ_SOURCE_DIO_OVER_TEMP) {
84 PERROR("Invalid interrupt source specified.\n");
85 return ME_ERRNO_INVALID_IRQ_SOURCE;
86 }
87
88 PDEBUG("executed.\n");
89
90 instance = (me8200_do_subdevice_t *) subdevice;
91
92 ME_SUBDEVICE_ENTER;
93
94 spin_lock_irqsave(&instance->subdevice_lock, status);
95 spin_lock(instance->irq_mode_lock);
96 tmp = inb(instance->irq_ctrl_reg);
97 tmp |=
98 ME8200_IRQ_MODE_BIT_ENABLE_POWER << (ME8200_IRQ_MODE_POWER_SHIFT *
99 instance->do_idx);
100 outb(tmp, instance->irq_ctrl_reg);
101 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
102 instance->irq_ctrl_reg - instance->reg_base, tmp);
103 spin_unlock(instance->irq_mode_lock);
104 instance->rised = 0;
105 spin_unlock_irqrestore(&instance->subdevice_lock, status);
106
107 ME_SUBDEVICE_EXIT;
108
109 return err;
110}
111
112static int me8200_do_io_irq_wait(me_subdevice_t * subdevice,
113 struct file *filep,
114 int channel,
115 int *irq_count,
116 int *value, int time_out, int flags)
117{
118 me8200_do_subdevice_t *instance;
119 int err = ME_ERRNO_SUCCESS;
120 long t = 0;
121 unsigned long cpu_flags;
122
123 PDEBUG("executed.\n");
124
125 instance = (me8200_do_subdevice_t *) subdevice;
126
127 if (flags) {
128 PERROR("Invalid flag specified.\n");
129 return ME_ERRNO_INVALID_FLAGS;
130 }
131
132 if (time_out < 0) {
133 PERROR("Invalid time_out specified.\n");
134 return ME_ERRNO_INVALID_TIMEOUT;
135 }
136
137 if (time_out) {
138 t = (time_out * HZ) / 1000;
139
140 if (t == 0)
141 t = 1;
142 }
143
144 ME_SUBDEVICE_ENTER;
145
146 if (instance->rised <= 0) {
147 instance->rised = 0;
148
149 if (time_out) {
150 t = wait_event_interruptible_timeout(instance->
151 wait_queue,
152 (instance->rised !=
153 0), t);
154
155 if (t == 0) {
156 PERROR
157 ("Wait on external interrupt timed out.\n");
158 err = ME_ERRNO_TIMEOUT;
159 }
160 } else {
161 wait_event_interruptible(instance->wait_queue,
162 (instance->rised != 0));
163 }
164
165 if (instance->rised < 0) {
166 PERROR("Wait on interrupt aborted by user.\n");
167 err = ME_ERRNO_CANCELLED;
168 }
169 }
170
171 if (signal_pending(current)) {
172 PERROR("Wait on external interrupt aborted by signal.\n");
173 err = ME_ERRNO_SIGNAL;
174 }
175
176 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
177 instance->rised = 0;
178 *irq_count = instance->count;
179 *value = 0;
180 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
181
182 ME_SUBDEVICE_EXIT;
183
184 return err;
185}
186
187static int me8200_do_io_irq_stop(me_subdevice_t * subdevice,
188 struct file *filep, int channel, int flags)
189{
190 me8200_do_subdevice_t *instance;
191 uint8_t tmp;
192 unsigned long cpu_flags;
193
194 PDEBUG("executed.\n");
195
196 instance = (me8200_do_subdevice_t *) subdevice;
197
198 if (flags) {
199 PERROR("Invalid flag specified.\n");
200 return ME_ERRNO_INVALID_FLAGS;
201 }
202
203 ME_SUBDEVICE_ENTER;
204
205 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
206 spin_lock(instance->irq_mode_lock);
207 tmp = inb(instance->irq_ctrl_reg);
208 tmp &=
209 ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER <<
210 (ME8200_IRQ_MODE_POWER_SHIFT * instance->do_idx));
211 outb(tmp, instance->irq_ctrl_reg);
212 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
213 instance->irq_ctrl_reg - instance->reg_base, tmp);
214 spin_unlock(instance->irq_mode_lock);
215 instance->rised = -1;
216 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
217 wake_up_interruptible_all(&instance->wait_queue);
218
219 ME_SUBDEVICE_EXIT;
220
221 return ME_ERRNO_SUCCESS;
222}
223
224static int me8200_do_io_reset_subdevice(struct me_subdevice *subdevice,
225 struct file *filep, int flags)
226{
227 me8200_do_subdevice_t *instance;
228 unsigned long cpu_flags;
229 uint8_t tmp;
230
231 PDEBUG("executed.\n");
232
233 instance = (me8200_do_subdevice_t *) subdevice;
234
235 if (flags) {
236 PERROR("Invalid flag specified.\n");
237 return ME_ERRNO_INVALID_FLAGS;
238 }
239
240 ME_SUBDEVICE_ENTER;
241
242 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
243 outb(0x00, instance->port_reg);
244 PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
245 instance->port_reg - instance->reg_base, 0x00);
246 spin_lock(instance->irq_mode_lock);
247 tmp = inb(instance->irq_ctrl_reg);
248 tmp &=
249 ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER <<
250 (ME8200_IRQ_MODE_POWER_SHIFT * instance->do_idx));
251 outb(tmp, instance->irq_ctrl_reg);
252 PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
253 instance->irq_ctrl_reg - instance->reg_base, tmp);
254 spin_unlock(instance->irq_mode_lock);
255 instance->rised = -1;
256 instance->count = 0;
257 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
258 wake_up_interruptible_all(&instance->wait_queue);
259
260 ME_SUBDEVICE_EXIT;
261
262 return ME_ERRNO_SUCCESS;
263}
264
265static int me8200_do_io_single_config(me_subdevice_t * subdevice,
266 struct file *filep,
267 int channel,
268 int single_config,
269 int ref,
270 int trig_chan,
271 int trig_type, int trig_edge, int flags)
272{
273 me8200_do_subdevice_t *instance;
274 int err = ME_ERRNO_SUCCESS;
275 unsigned long status;
276
277 PDEBUG("executed.\n");
278
279 instance = (me8200_do_subdevice_t *) subdevice;
280
281 ME_SUBDEVICE_ENTER;
282
283 spin_lock_irqsave(&instance->subdevice_lock, status);
284 switch (flags) {
285 case ME_IO_SINGLE_CONFIG_NO_FLAGS:
286 case ME_IO_SINGLE_CONFIG_DIO_BYTE:
287 if (channel == 0) {
288 if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
289 } else {
290 PERROR("Invalid byte direction specified.\n");
291 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
292 }
293 } else {
294 PERROR("Invalid byte specified.\n");
295 err = ME_ERRNO_INVALID_CHANNEL;
296 }
297 break;
298
299 default:
300 PERROR("Invalid flags specified.\n");
301 err = ME_ERRNO_INVALID_FLAGS;
302 }
303 spin_unlock_irqrestore(&instance->subdevice_lock, status);
304
305 ME_SUBDEVICE_EXIT;
306
307 return err;
308}
309
310static int me8200_do_io_single_read(me_subdevice_t * subdevice,
311 struct file *filep,
312 int channel,
313 int *value, int time_out, int flags)
314{
315 me8200_do_subdevice_t *instance;
316 int err = ME_ERRNO_SUCCESS;
317 unsigned long status;
318
319 PDEBUG("executed.\n");
320
321 instance = (me8200_do_subdevice_t *) subdevice;
322
323 ME_SUBDEVICE_ENTER;
324
325 spin_lock_irqsave(&instance->subdevice_lock, status);
326 switch (flags) {
327 case ME_IO_SINGLE_TYPE_DIO_BIT:
328 if ((channel >= 0) && (channel < 8)) {
329 *value = inb(instance->port_reg) & (0x1 << channel);
330 } else {
331 PERROR("Invalid bit number specified.\n");
332 err = ME_ERRNO_INVALID_CHANNEL;
333 }
334 break;
335
336 case ME_IO_SINGLE_NO_FLAGS:
337 case ME_IO_SINGLE_TYPE_DIO_BYTE:
338 if (channel == 0) {
339 *value = inb(instance->port_reg);
340 } else {
341 PERROR("Invalid byte number specified.\n");
342 err = ME_ERRNO_INVALID_CHANNEL;
343 }
344 break;
345
346 default:
347 PERROR("Invalid flags specified.\n");
348 err = ME_ERRNO_INVALID_FLAGS;
349 }
350 spin_unlock_irqrestore(&instance->subdevice_lock, status);
351
352 ME_SUBDEVICE_EXIT;
353
354 return err;
355}
356
357static int me8200_do_io_single_write(me_subdevice_t * subdevice,
358 struct file *filep,
359 int channel,
360 int value, int time_out, int flags)
361{
362 me8200_do_subdevice_t *instance;
363 int err = ME_ERRNO_SUCCESS;
364 uint8_t state;
365 unsigned long status;
366
367 PDEBUG("executed.\n");
368
369 instance = (me8200_do_subdevice_t *) subdevice;
370
371 ME_SUBDEVICE_ENTER;
372
373 spin_lock_irqsave(&instance->subdevice_lock, status);
374 switch (flags) {
375 case ME_IO_SINGLE_TYPE_DIO_BIT:
376 if ((channel >= 0) && (channel < 8)) {
377 state = inb(instance->port_reg);
378 state =
379 value ? (state | (0x1 << channel)) : (state &
380 ~(0x1 <<
381 channel));
382 outb(state, instance->port_reg);
383 PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n",
384 instance->reg_base,
385 instance->port_reg - instance->reg_base,
386 state);
387 } else {
388 PERROR("Invalid bit number specified.\n");
389 err = ME_ERRNO_INVALID_CHANNEL;
390 }
391 break;
392
393 case ME_IO_SINGLE_NO_FLAGS:
394 case ME_IO_SINGLE_TYPE_DIO_BYTE:
395 if (channel == 0) {
396 outb(value, instance->port_reg);
397 PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n",
398 instance->reg_base,
399 instance->port_reg - instance->reg_base,
400 value);
401 } else {
402 PERROR("Invalid byte number specified.\n");
403 err = ME_ERRNO_INVALID_CHANNEL;
404 }
405 break;
406
407 default:
408 PERROR("Invalid flags specified.\n");
409 err = ME_ERRNO_INVALID_FLAGS;
410 }
411 spin_unlock_irqrestore(&instance->subdevice_lock, status);
412
413 ME_SUBDEVICE_EXIT;
414
415 return err;
416}
417
418static int me8200_do_query_number_channels(me_subdevice_t * subdevice,
419 int *number)
420{
421 PDEBUG("executed.\n");
422 *number = 8;
423 return ME_ERRNO_SUCCESS;
424}
425
426static int me8200_do_query_subdevice_type(me_subdevice_t * subdevice,
427 int *type, int *subtype)
428{
429 PDEBUG("executed.\n");
430 *type = ME_TYPE_DO;
431 *subtype = ME_SUBTYPE_SINGLE;
432 return ME_ERRNO_SUCCESS;
433}
434
435static int me8200_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
436{
437 PDEBUG("executed.\n");
438 *caps = ME_CAPS_DIO_OVER_TEMP_IRQ;
439 return ME_ERRNO_SUCCESS;
440}
441
442static void me8200_do_destructor(struct me_subdevice *subdevice)
443{
444 me8200_do_subdevice_t *instance;
445
446 PDEBUG("executed.\n");
447
448 instance = (me8200_do_subdevice_t *) subdevice;
449
450 free_irq(instance->irq, (void *)instance);
451 me_subdevice_deinit(&instance->base);
452 kfree(instance);
453}
454
455#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
456static irqreturn_t me8200_do_isr(int irq, void *dev_id)
457#else
458static irqreturn_t me8200_do_isr(int irq, void *dev_id, struct pt_regs *regs)
459#endif
460{
461 me8200_do_subdevice_t *instance;
462 uint16_t ctrl;
463 uint8_t irq_status;
464
465 instance = (me8200_do_subdevice_t *) dev_id;
466
467 if (irq != instance->irq) {
468 PERROR("Incorrect interrupt num: %d.\n", irq);
469 return IRQ_NONE;
470 }
471
472 irq_status = inb(instance->irq_status_reg);
473 if (!
474 (irq_status &
475 (ME8200_DO_IRQ_STATUS_BIT_ACTIVE << instance->do_idx))) {
476 PINFO
477 ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
478 jiffies, __FUNCTION__, instance->do_idx, irq_status);
479 return IRQ_NONE;
480 }
481
482 PDEBUG("executed.\n");
483
484 spin_lock(&instance->subdevice_lock);
485 instance->rised = 1;
486 instance->count++;
487
488 spin_lock(instance->irq_mode_lock);
489 ctrl = inw(instance->irq_ctrl_reg);
490 ctrl |= ME8200_IRQ_MODE_BIT_CLEAR_POWER << instance->do_idx;
491 outw(ctrl, instance->irq_ctrl_reg);
492 PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
493 instance->irq_ctrl_reg - instance->reg_base, ctrl);
494 ctrl &= ~(ME8200_IRQ_MODE_BIT_CLEAR_POWER << instance->do_idx);
495 outw(ctrl, instance->irq_ctrl_reg);
496 PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
497 instance->irq_ctrl_reg - instance->reg_base, ctrl);
498 spin_unlock(instance->irq_mode_lock);
499 spin_unlock(&instance->subdevice_lock);
500 wake_up_interruptible_all(&instance->wait_queue);
501
502 return IRQ_HANDLED;
503}
504
505me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base,
506 unsigned int do_idx,
507 int irq,
508 spinlock_t * irq_mode_lock)
509{
510 me8200_do_subdevice_t *subdevice;
511 int err;
512
513 PDEBUG("executed.\n");
514
515 /* Allocate memory for subdevice instance */
516 subdevice = kmalloc(sizeof(me8200_do_subdevice_t), GFP_KERNEL);
517
518 if (!subdevice) {
519 PERROR("Cannot get memory for subdevice instance.\n");
520 return NULL;
521 }
522
523 memset(subdevice, 0, sizeof(me8200_do_subdevice_t));
524
525 /* Initialize subdevice base class */
526 err = me_subdevice_init(&subdevice->base);
527
528 if (err) {
529 PERROR("Cannot initialize subdevice base class instance.\n");
530 kfree(subdevice);
531 return NULL;
532 }
533 // Initialize spin locks.
534 spin_lock_init(&subdevice->subdevice_lock);
535
536 subdevice->irq_mode_lock = irq_mode_lock;
537
538 /* Save the index of the digital output */
539 subdevice->do_idx = do_idx;
540 subdevice->irq = irq;
541
542 /* Initialize the registers */
543 if (do_idx == 0) {
544 subdevice->port_reg = reg_base + ME8200_DO_PORT_0_REG;
545 } else if (do_idx == 1) {
546 subdevice->port_reg = reg_base + ME8200_DO_PORT_1_REG;
547 } else {
548 PERROR("Wrong subdevice idx=%d.\n", do_idx);
549 kfree(subdevice);
550 return NULL;
551 }
552 subdevice->irq_ctrl_reg = reg_base + ME8200_IRQ_MODE_REG;
553 subdevice->irq_status_reg = reg_base + ME8200_DO_IRQ_STATUS_REG;
554#ifdef MEDEBUG_DEBUG_REG
555 subdevice->reg_base = reg_base;
556#endif
557
558 /* Initialize the wait queue */
559 init_waitqueue_head(&subdevice->wait_queue);
560
561 /* Request the interrupt line */
562 err = request_irq(irq, me8200_do_isr,
563#ifdef IRQF_DISABLED
564 IRQF_DISABLED | IRQF_SHARED,
565#else
566 SA_INTERRUPT | SA_SHIRQ,
567#endif
568 ME8200_NAME, (void *)subdevice);
569
570 if (err) {
571 PERROR("Cannot get interrupt line.\n");
572 kfree(subdevice);
573 return NULL;
574 }
575 PINFO("Registered irq=%d.\n", irq);
576
577 /* Overload base class methods. */
578 subdevice->base.me_subdevice_io_irq_start = me8200_do_io_irq_start;
579 subdevice->base.me_subdevice_io_irq_wait = me8200_do_io_irq_wait;
580 subdevice->base.me_subdevice_io_irq_stop = me8200_do_io_irq_stop;
581 subdevice->base.me_subdevice_io_reset_subdevice =
582 me8200_do_io_reset_subdevice;
583 subdevice->base.me_subdevice_io_single_config =
584 me8200_do_io_single_config;
585 subdevice->base.me_subdevice_io_single_read = me8200_do_io_single_read;
586 subdevice->base.me_subdevice_io_single_write =
587 me8200_do_io_single_write;
588 subdevice->base.me_subdevice_query_number_channels =
589 me8200_do_query_number_channels;
590 subdevice->base.me_subdevice_query_subdevice_type =
591 me8200_do_query_subdevice_type;
592 subdevice->base.me_subdevice_query_subdevice_caps =
593 me8200_do_query_subdevice_caps;
594 subdevice->base.me_subdevice_destructor = me8200_do_destructor;
595
596 subdevice->rised = 0;
597 subdevice->count = 0;
598
599 return subdevice;
600}
diff --git a/drivers/staging/meilhaus/me8200_do.h b/drivers/staging/meilhaus/me8200_do.h
new file mode 100644
index 000000000000..27581251c847
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_do.h
@@ -0,0 +1,75 @@
1/**
2 * @file me8200_do.h
3 *
4 * @brief ME-8200 digital output subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8200_DO_H_
28#define _ME8200_DO_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The template subdevice class.
36 */
37typedef struct me8200_do_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *irq_mode_lock;
44
45 int irq; /**< The number of the interrupt request */
46 int rised; /**< Flag to indicate if an interrupt occured */
47 int count; /**< Counts the number of interrupts occured */
48 wait_queue_head_t wait_queue; /**< To wait on interrupts */
49
50 unsigned int do_idx; /**< The number of the digital output */
51
52 unsigned long port_reg; /**< The digital output port */
53 unsigned long irq_ctrl_reg; /**< The interrupt control register */
54 unsigned long irq_status_reg; /**< The interrupt status register */
55#ifdef MEDEBUG_DEBUG_REG
56 unsigned long reg_base;
57#endif
58} me8200_do_subdevice_t;
59
60/**
61 * @brief The constructor to generate a ME-8200 digital output subdevice instance.
62 *
63 * @param reg_base The register base address of the device as returned by the PCI BIOS.
64 * @param do_idx The index of the digital output subdevice on this device.
65 *
66 * @return Pointer to new instance on success.\n
67 * NULL on error.
68 */
69me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base,
70 unsigned int do_idx,
71 int irq,
72 spinlock_t * irq_mode_lock);
73
74#endif
75#endif
diff --git a/drivers/staging/meilhaus/me8200_do_reg.h b/drivers/staging/meilhaus/me8200_do_reg.h
new file mode 100644
index 000000000000..41095046037a
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_do_reg.h
@@ -0,0 +1,40 @@
1/**
2 * @file me8200_ao_reg.h
3 *
4 * @brief ME-8200 analog output subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8200_DO_REG_H_
28#define _ME8200_DO_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME8200_DO_IRQ_STATUS_REG 0x0 // R
33#define ME8200_DO_PORT_0_REG 0x1 // R/W
34#define ME8200_DO_PORT_1_REG 0x2 // R/W
35
36#define ME8200_DO_IRQ_STATUS_BIT_ACTIVE 0x1
37#define ME8200_DO_IRQ_STATUS_SHIFT 1
38
39#endif
40#endif
diff --git a/drivers/staging/meilhaus/me8200_reg.h b/drivers/staging/meilhaus/me8200_reg.h
new file mode 100644
index 000000000000..a73fe4d5b0ff
--- /dev/null
+++ b/drivers/staging/meilhaus/me8200_reg.h
@@ -0,0 +1,46 @@
1/**
2 * @file me8200_reg.h
3 *
4 * @brief ME-8200 register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8200_REG_H_
28#define _ME8200_REG_H_
29
30#ifdef __KERNEL__
31
32#define ME8200_IRQ_MODE_REG 0xD // R/W
33
34#define ME8200_IRQ_MODE_MASK 0x3
35
36#define ME8200_IRQ_MODE_MASK_MASK 0x0
37#define ME8200_IRQ_MODE_MASK_COMPARE 0x1
38
39#define ME8200_IRQ_MODE_BIT_ENABLE_POWER 0x10
40#define ME8200_IRQ_MODE_BIT_CLEAR_POWER 0x40
41
42#define ME8200_IRQ_MODE_DI_SHIFT 2
43#define ME8200_IRQ_MODE_POWER_SHIFT 1
44
45#endif
46#endif
diff --git a/drivers/staging/meilhaus/me8254.c b/drivers/staging/meilhaus/me8254.c
new file mode 100644
index 000000000000..6e44c3d7a0c7
--- /dev/null
+++ b/drivers/staging/meilhaus/me8254.c
@@ -0,0 +1,1176 @@
1/**
2 * @file me8254.c
3 *
4 * @brief 8254 subdevice instance.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef __KERNEL__
28# define __KERNEL__
29#endif
30
31/*
32 * Includes
33 */
34#include <linux/module.h>
35
36#include <linux/slab.h>
37#include <linux/spinlock.h>
38#include <asm/io.h>
39#include <linux/types.h>
40
41#include "medefines.h"
42#include "meinternal.h"
43#include "meerror.h"
44
45#include "medebug.h"
46#include "me8254_reg.h"
47#include "me8254.h"
48
49/*
50 * Defines
51 */
52#define ME8254_NUMBER_CHANNELS 1 /**< One channel per counter. */
53#define ME8254_CTR_WIDTH 16 /**< One counter has 16 bits. */
54
55/*
56 * Functions
57 */
58
59static int me8254_io_reset_subdevice(struct me_subdevice *subdevice,
60 struct file *filep, int flags)
61{
62 me8254_subdevice_t *instance;
63 uint8_t clk_src;
64 int err = ME_ERRNO_SUCCESS;
65
66 PDEBUG("executed.\n");
67
68 instance = (me8254_subdevice_t *) subdevice;
69
70 if (flags) {
71 PERROR("Invalid flag specified.\n");
72 return ME_ERRNO_INVALID_FLAGS;
73 }
74
75 ME_SUBDEVICE_ENTER;
76
77 spin_lock(&instance->subdevice_lock);
78 spin_lock(instance->ctrl_reg_lock);
79 if (instance->ctr_idx == 0)
80 outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
81 ME8254_CTRL_BIN, instance->ctrl_reg);
82 else if (instance->ctr_idx == 1)
83 outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
84 ME8254_CTRL_BIN, instance->ctrl_reg);
85 else
86 outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
87 ME8254_CTRL_BIN, instance->ctrl_reg);
88 spin_unlock(instance->ctrl_reg_lock);
89
90 outb(0x00, instance->val_reg);
91 outb(0x00, instance->val_reg);
92
93 spin_lock(instance->clk_src_reg_lock);
94 clk_src = inb(instance->clk_src_reg);
95
96 switch (instance->device_id) {
97 case PCI_DEVICE_ID_MEILHAUS_ME1400:
98 case PCI_DEVICE_ID_MEILHAUS_ME140A:
99 case PCI_DEVICE_ID_MEILHAUS_ME140B:
100 case PCI_DEVICE_ID_MEILHAUS_ME14E0:
101 case PCI_DEVICE_ID_MEILHAUS_ME14EA:
102 case PCI_DEVICE_ID_MEILHAUS_ME14EB:
103 if (instance->me8254_idx == 0) {
104 if (instance->ctr_idx == 0)
105 clk_src &=
106 ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ |
107 ME1400AB_8254_A_0_CLK_SRC_QUARZ);
108 else if (instance->ctr_idx == 1)
109 clk_src &= ~(ME1400AB_8254_A_1_CLK_SRC_PREV);
110 else
111 clk_src &= ~(ME1400AB_8254_A_2_CLK_SRC_PREV);
112 } else {
113 if (instance->ctr_idx == 0)
114 clk_src &=
115 ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ |
116 ME1400AB_8254_B_0_CLK_SRC_QUARZ);
117 else if (instance->ctr_idx == 1)
118 clk_src &= ~(ME1400AB_8254_B_1_CLK_SRC_PREV);
119 else
120 clk_src &= ~(ME1400AB_8254_B_2_CLK_SRC_PREV);
121 }
122 break;
123
124 case PCI_DEVICE_ID_MEILHAUS_ME140C:
125 case PCI_DEVICE_ID_MEILHAUS_ME140D:
126 switch (instance->me8254_idx) {
127 case 0:
128 case 2:
129 case 4:
130 case 6:
131 case 8:
132 if (instance->ctr_idx == 0)
133 clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
134 else if (instance->ctr_idx == 1)
135 clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK);
136 else
137 clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK);
138 break;
139
140 default:
141 if (instance->ctr_idx == 0)
142 clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
143 else if (instance->ctr_idx == 1)
144 clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK);
145 else
146 clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK);
147 break;
148 }
149 break;
150
151 case PCI_DEVICE_ID_MEILHAUS_ME4610:
152 case PCI_DEVICE_ID_MEILHAUS_ME4660:
153 case PCI_DEVICE_ID_MEILHAUS_ME4660I:
154 case PCI_DEVICE_ID_MEILHAUS_ME4660S:
155 case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
156 case PCI_DEVICE_ID_MEILHAUS_ME4670:
157 case PCI_DEVICE_ID_MEILHAUS_ME4670I:
158 case PCI_DEVICE_ID_MEILHAUS_ME4670S:
159 case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
160 case PCI_DEVICE_ID_MEILHAUS_ME4680:
161 case PCI_DEVICE_ID_MEILHAUS_ME4680I:
162 case PCI_DEVICE_ID_MEILHAUS_ME4680S:
163 case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
164 case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
165 case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
166
167 /* No clock source register available */
168 break;
169
170 default:
171 PERROR("Invalid device type.\n");
172 err = ME_ERRNO_INTERNAL;
173 }
174
175 if (!err)
176 outb(clk_src, instance->clk_src_reg);
177
178 spin_unlock(instance->clk_src_reg_lock);
179 spin_unlock(&instance->subdevice_lock);
180
181 ME_SUBDEVICE_EXIT;
182
183 return err;
184}
185
186static int me1400_ab_ref_config(me8254_subdevice_t * instance, int ref)
187{
188 uint8_t clk_src;
189
190 spin_lock(instance->clk_src_reg_lock);
191 clk_src = inb(instance->clk_src_reg);
192
193 switch (ref) {
194 case ME_REF_CTR_EXTERNAL:
195 if (instance->me8254_idx == 0) {
196 if (instance->ctr_idx == 0)
197 clk_src &= ~(ME1400AB_8254_A_0_CLK_SRC_QUARZ);
198 else if (instance->ctr_idx == 1)
199 clk_src &= ~(ME1400AB_8254_A_1_CLK_SRC_PREV);
200 else
201 clk_src &= ~(ME1400AB_8254_A_2_CLK_SRC_PREV);
202 } else {
203 if (instance->ctr_idx == 0)
204 clk_src &= ~(ME1400AB_8254_B_0_CLK_SRC_QUARZ);
205 else if (instance->ctr_idx == 1)
206 clk_src &= ~(ME1400AB_8254_B_1_CLK_SRC_PREV);
207 else
208 clk_src &= ~(ME1400AB_8254_B_2_CLK_SRC_PREV);
209 }
210
211 break;
212
213 case ME_REF_CTR_PREVIOUS:
214 if (instance->me8254_idx == 0) {
215 if (instance->ctr_idx == 0) {
216 PERROR("Invalid reference.\n");
217 spin_unlock(instance->clk_src_reg_lock);
218 return ME_ERRNO_INVALID_SINGLE_CONFIG;
219 } else if (instance->ctr_idx == 1)
220 clk_src |= (ME1400AB_8254_A_1_CLK_SRC_PREV);
221 else
222 clk_src |= (ME1400AB_8254_A_2_CLK_SRC_PREV);
223 } else {
224 if (instance->ctr_idx == 0) {
225 PERROR("Invalid reference.\n");
226 spin_unlock(instance->clk_src_reg_lock);
227 return ME_ERRNO_INVALID_SINGLE_CONFIG;
228 } else if (instance->ctr_idx == 1)
229 clk_src |= (ME1400AB_8254_B_1_CLK_SRC_PREV);
230 else
231 clk_src |= (ME1400AB_8254_B_2_CLK_SRC_PREV);
232 }
233
234 break;
235
236 case ME_REF_CTR_INTERNAL_1MHZ:
237 if (instance->me8254_idx == 0) {
238 if (instance->ctr_idx == 0) {
239 clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ);
240 clk_src &= ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ);
241 } else {
242 PERROR("Invalid reference.\n");
243 spin_unlock(instance->clk_src_reg_lock);
244 return ME_ERRNO_INVALID_SINGLE_CONFIG;
245 }
246 } else {
247 if (instance->ctr_idx == 0) {
248 clk_src |= (ME1400AB_8254_B_0_CLK_SRC_QUARZ);
249 clk_src &= ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ);
250 } else {
251 PERROR("Invalid reference.\n");
252 spin_unlock(instance->clk_src_reg_lock);
253 return ME_ERRNO_INVALID_SINGLE_CONFIG;
254 }
255 }
256
257 break;
258
259 case ME_REF_CTR_INTERNAL_10MHZ:
260 if (instance->me8254_idx == 0) {
261 if (instance->ctr_idx == 0) {
262 clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ);
263 clk_src |= (ME1400AB_8254_A_0_CLK_SRC_10MHZ);
264 } else {
265 PERROR("Invalid reference.\n");
266 spin_unlock(instance->clk_src_reg_lock);
267 return ME_ERRNO_INVALID_SINGLE_CONFIG;
268 }
269 } else {
270 if (instance->ctr_idx == 0) {
271 clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ);
272 clk_src |= (ME1400AB_8254_A_0_CLK_SRC_10MHZ);
273 } else {
274 PERROR("Invalid reference.\n");
275 spin_unlock(instance->clk_src_reg_lock);
276 return ME_ERRNO_INVALID_SINGLE_CONFIG;
277 }
278 }
279
280 break;
281
282 default:
283 PERROR("Invalid reference.\n");
284 spin_unlock(instance->clk_src_reg_lock);
285 return ME_ERRNO_INVALID_REF;
286 }
287
288 outb(clk_src, instance->clk_src_reg);
289 spin_unlock(instance->clk_src_reg_lock);
290
291 return ME_ERRNO_SUCCESS;
292}
293
294static int me1400_cd_ref_config(me8254_subdevice_t * instance, int ref)
295{
296 uint8_t clk_src;
297
298 spin_lock(instance->clk_src_reg_lock);
299 clk_src = inb(instance->clk_src_reg);
300
301 switch (ref) {
302 case ME_REF_CTR_EXTERNAL:
303 switch (instance->me8254_idx) {
304 case 0:
305 case 2:
306 case 4:
307 case 6:
308 case 8:
309 if (instance->ctr_idx == 0)
310 clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
311 else if (instance->ctr_idx == 1)
312 clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK);
313 else
314 clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK);
315 break;
316
317 default:
318 if (instance->ctr_idx == 0)
319 clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
320 else if (instance->ctr_idx == 1)
321 clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK);
322 else
323 clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK);
324 break;
325 }
326 break;
327
328 case ME_REF_CTR_PREVIOUS:
329 switch (instance->me8254_idx) {
330 case 0:
331 case 2:
332 case 4:
333 case 6:
334 case 8:
335 if (instance->ctr_idx == 0) {
336 clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
337 clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_PREV);
338 } else if (instance->ctr_idx == 1) {
339 clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK);
340 clk_src |= (ME1400CD_8254_ACE_1_CLK_SRC_PREV);
341 } else {
342 clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK);
343 clk_src |= (ME1400CD_8254_ACE_2_CLK_SRC_PREV);
344 }
345 break;
346
347 default:
348 if (instance->ctr_idx == 0) {
349 clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
350 clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_PREV);
351 } else if (instance->ctr_idx == 1) {
352 clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK);
353 clk_src |= (ME1400CD_8254_BD_1_CLK_SRC_PREV);
354 } else {
355 clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK);
356 clk_src |= (ME1400CD_8254_BD_2_CLK_SRC_PREV);
357 }
358 break;
359 }
360
361 break;
362
363 case ME_REF_CTR_INTERNAL_1MHZ:
364 switch (instance->me8254_idx) {
365 case 0:
366 case 2:
367 case 4:
368 case 6:
369 case 8:
370 if (instance->ctr_idx == 0) {
371 clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
372 clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_1MHZ);
373 } else {
374 PERROR("Invalid reference.\n");
375 spin_unlock(instance->clk_src_reg_lock);
376 return ME_ERRNO_INVALID_REF;
377 }
378
379 break;
380
381 default:
382 if (instance->ctr_idx == 0) {
383 clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
384 clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_1MHZ);
385 } else {
386 PERROR("Invalid reference.\n");
387 spin_unlock(instance->clk_src_reg_lock);
388 return ME_ERRNO_INVALID_REF;
389 }
390 break;
391 }
392
393 break;
394
395 case ME_REF_CTR_INTERNAL_10MHZ:
396 switch (instance->me8254_idx) {
397 case 0:
398 case 2:
399 case 4:
400 case 6:
401 case 8:
402 if (instance->ctr_idx == 0) {
403 clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
404 clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_10MHZ);
405 } else {
406 PERROR("Invalid reference.\n");
407 spin_unlock(instance->clk_src_reg_lock);
408 return ME_ERRNO_INVALID_REF;
409 }
410 break;
411
412 default:
413 if (instance->ctr_idx == 0) {
414 clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
415 clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_10MHZ);
416 } else {
417 PERROR("Invalid reference.\n");
418 spin_unlock(instance->clk_src_reg_lock);
419 return ME_ERRNO_INVALID_REF;
420 }
421
422 break;
423 }
424
425 break;
426
427 default:
428 PERROR("Invalid reference.\n");
429 spin_unlock(instance->clk_src_reg_lock);
430 return ME_ERRNO_INVALID_REF;
431 }
432
433 outb(clk_src, instance->clk_src_reg);
434 spin_unlock(instance->clk_src_reg_lock);
435
436 return ME_ERRNO_SUCCESS;
437}
438
439static int me4600_ref_config(me8254_subdevice_t * instance, int ref)
440{
441 switch (ref) {
442
443 case ME_REF_CTR_EXTERNAL:
444 // Nothing to do
445 break;
446
447 default:
448 PERROR("Invalid reference.\n");
449// spin_unlock(instance->clk_src_reg_lock);
450 return ME_ERRNO_INVALID_REF;
451 }
452
453 return ME_ERRNO_SUCCESS;
454}
455
456static int me8100_ref_config(me8254_subdevice_t * instance, int ref)
457{
458 switch (ref) {
459
460 case ME_REF_CTR_EXTERNAL:
461 // Nothing to do
462 break;
463
464 default:
465 PERROR("Invalid reference.\n");
466// spin_unlock(instance->clk_src_reg_lock);
467 return ME_ERRNO_INVALID_REF;
468 }
469
470 return ME_ERRNO_SUCCESS;
471}
472
473static int me8254_io_single_config(struct me_subdevice *subdevice,
474 struct file *filep,
475 int channel,
476 int single_config,
477 int ref,
478 int trig_chan,
479 int trig_type, int trig_edge, int flags)
480{
481 me8254_subdevice_t *instance;
482 int err;
483
484 PDEBUG("executed.\n");
485
486 if (channel) {
487 PERROR("Invalid channel.\n");
488 return ME_ERRNO_INVALID_CHANNEL;
489 }
490
491 instance = (me8254_subdevice_t *) subdevice;
492
493 if (flags) {
494 PERROR("Invalid flag specified.\n");
495 return ME_ERRNO_INVALID_FLAGS;
496 }
497
498 ME_SUBDEVICE_ENTER;
499
500 spin_lock(&instance->subdevice_lock);
501 // Configure the counter modes
502 if (instance->ctr_idx == 0) {
503 if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) {
504 outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
505 ME8254_CTRL_BIN, instance->ctrl_reg);
506 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) {
507 outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M1 |
508 ME8254_CTRL_BIN, instance->ctrl_reg);
509 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) {
510 outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M2 |
511 ME8254_CTRL_BIN, instance->ctrl_reg);
512 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) {
513 outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M3 |
514 ME8254_CTRL_BIN, instance->ctrl_reg);
515 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) {
516 outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M4 |
517 ME8254_CTRL_BIN, instance->ctrl_reg);
518 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) {
519 outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M5 |
520 ME8254_CTRL_BIN, instance->ctrl_reg);
521 } else {
522 PERROR("Invalid single configuration.\n");
523 spin_unlock(&instance->subdevice_lock);
524 return ME_ERRNO_INVALID_SINGLE_CONFIG;
525 }
526 } else if (instance->ctr_idx == 1) {
527 if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) {
528 outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
529 ME8254_CTRL_BIN, instance->ctrl_reg);
530 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) {
531 outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M1 |
532 ME8254_CTRL_BIN, instance->ctrl_reg);
533 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) {
534 outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M2 |
535 ME8254_CTRL_BIN, instance->ctrl_reg);
536 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) {
537 outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M3 |
538 ME8254_CTRL_BIN, instance->ctrl_reg);
539 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) {
540 outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M4 |
541 ME8254_CTRL_BIN, instance->ctrl_reg);
542 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) {
543 outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M5 |
544 ME8254_CTRL_BIN, instance->ctrl_reg);
545 } else {
546 PERROR("Invalid single configuration.\n");
547 spin_unlock(&instance->subdevice_lock);
548 return ME_ERRNO_INVALID_SINGLE_CONFIG;
549 }
550 } else {
551 if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) {
552 outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
553 ME8254_CTRL_BIN, instance->ctrl_reg);
554 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) {
555 outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M1 |
556 ME8254_CTRL_BIN, instance->ctrl_reg);
557 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) {
558 outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M2 |
559 ME8254_CTRL_BIN, instance->ctrl_reg);
560 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) {
561 outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M3 |
562 ME8254_CTRL_BIN, instance->ctrl_reg);
563 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) {
564 outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M4 |
565 ME8254_CTRL_BIN, instance->ctrl_reg);
566 } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) {
567 outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M5 |
568 ME8254_CTRL_BIN, instance->ctrl_reg);
569 } else {
570 PERROR("Invalid single configuration.\n");
571 spin_unlock(&instance->subdevice_lock);
572 return ME_ERRNO_INVALID_SINGLE_CONFIG;
573 }
574 }
575
576 switch (instance->device_id) {
577 case PCI_DEVICE_ID_MEILHAUS_ME1400:
578 case PCI_DEVICE_ID_MEILHAUS_ME14E0:
579 case PCI_DEVICE_ID_MEILHAUS_ME140A:
580 case PCI_DEVICE_ID_MEILHAUS_ME14EA:
581 case PCI_DEVICE_ID_MEILHAUS_ME140B:
582 case PCI_DEVICE_ID_MEILHAUS_ME14EB:
583 err = me1400_ab_ref_config(instance, ref);
584
585 if (err) {
586 spin_unlock(&instance->subdevice_lock);
587 return err;
588 }
589
590 break;
591
592 case PCI_DEVICE_ID_MEILHAUS_ME140C:
593 case PCI_DEVICE_ID_MEILHAUS_ME140D:
594 err = me1400_cd_ref_config(instance, ref);
595
596 if (err) {
597 spin_unlock(&instance->subdevice_lock);
598 return err;
599 }
600
601 break;
602
603 case PCI_DEVICE_ID_MEILHAUS_ME4610:
604 case PCI_DEVICE_ID_MEILHAUS_ME4660:
605 case PCI_DEVICE_ID_MEILHAUS_ME4660I:
606 case PCI_DEVICE_ID_MEILHAUS_ME4660S:
607 case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
608 case PCI_DEVICE_ID_MEILHAUS_ME4670:
609 case PCI_DEVICE_ID_MEILHAUS_ME4670I:
610 case PCI_DEVICE_ID_MEILHAUS_ME4670S:
611 case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
612 case PCI_DEVICE_ID_MEILHAUS_ME4680:
613 case PCI_DEVICE_ID_MEILHAUS_ME4680I:
614 case PCI_DEVICE_ID_MEILHAUS_ME4680S:
615 case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
616 err = me4600_ref_config(instance, ref);
617
618 if (err) {
619 spin_unlock(&instance->subdevice_lock);
620 return err;
621 }
622
623 break;
624
625 case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
626 case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
627 err = me8100_ref_config(instance, ref);
628
629 if (err) {
630 spin_unlock(&instance->subdevice_lock);
631 return err;
632 }
633
634 break;
635
636 default:
637 PERROR("Invalid device type.\n");
638
639 spin_unlock(&instance->subdevice_lock);
640// spin_unlock(instance->clk_src_reg_lock);
641 return ME_ERRNO_INVALID_SINGLE_CONFIG;
642 }
643 spin_unlock(&instance->subdevice_lock);
644
645 ME_SUBDEVICE_EXIT;
646
647 return ME_ERRNO_SUCCESS;
648}
649
650static int me8254_io_single_read(struct me_subdevice *subdevice,
651 struct file *filep,
652 int channel,
653 int *value, int time_out, int flags)
654{
655 me8254_subdevice_t *instance;
656 uint16_t lo_byte;
657 uint16_t hi_byte;
658
659 PDEBUG("executed.\n");
660
661 if (channel) {
662 PERROR("Invalid channel.\n");
663 return ME_ERRNO_INVALID_CHANNEL;
664 }
665
666 instance = (me8254_subdevice_t *) subdevice;
667
668 if (flags) {
669 PERROR("Invalid flag specified.\n");
670 return ME_ERRNO_INVALID_FLAGS;
671 }
672
673 ME_SUBDEVICE_ENTER;
674
675 spin_lock(&instance->subdevice_lock);
676 spin_lock(instance->ctrl_reg_lock);
677 if (instance->ctr_idx == 0)
678 outb(ME8254_CTRL_SC0 | ME8254_CTRL_TLO, instance->ctrl_reg);
679 else if (instance->ctr_idx == 1)
680 outb(ME8254_CTRL_SC1 | ME8254_CTRL_TLO, instance->ctrl_reg);
681 else
682 outb(ME8254_CTRL_SC2 | ME8254_CTRL_TLO, instance->ctrl_reg);
683
684 lo_byte = inb(instance->val_reg);
685 hi_byte = inb(instance->val_reg);
686 spin_unlock(instance->ctrl_reg_lock);
687
688 *value = lo_byte | (hi_byte << 8);
689 spin_unlock(&instance->subdevice_lock);
690
691 ME_SUBDEVICE_EXIT;
692
693 return ME_ERRNO_SUCCESS;
694}
695
696static int me8254_io_single_write(struct me_subdevice *subdevice,
697 struct file *filep,
698 int channel,
699 int value, int time_out, int flags)
700{
701 me8254_subdevice_t *instance;
702
703 PDEBUG("executed.\n");
704
705 if (channel) {
706 PERROR("Invalid channel.\n");
707 return ME_ERRNO_INVALID_CHANNEL;
708 }
709
710 instance = (me8254_subdevice_t *) subdevice;
711
712 if (flags) {
713 PERROR("Invalid flag specified.\n");
714 return ME_ERRNO_INVALID_FLAGS;
715 }
716
717 ME_SUBDEVICE_ENTER;
718
719 spin_lock(&instance->subdevice_lock);
720 outb(value, instance->val_reg);
721 outb((value >> 8), instance->val_reg);
722 spin_unlock(&instance->subdevice_lock);
723
724 ME_SUBDEVICE_EXIT;
725
726 return ME_ERRNO_SUCCESS;
727}
728
729static int me8254_query_number_channels(struct me_subdevice *subdevice,
730 int *number)
731{
732 PDEBUG("executed.\n");
733 *number = ME8254_NUMBER_CHANNELS;
734 return ME_ERRNO_SUCCESS;
735}
736
737static int me8254_query_subdevice_type(struct me_subdevice *subdevice,
738 int *type, int *subtype)
739{
740 PDEBUG("executed.\n");
741 *type = ME_TYPE_CTR;
742 *subtype = ME_SUBTYPE_CTR_8254;
743 return ME_ERRNO_SUCCESS;
744}
745
746static int me8254_query_subdevice_caps(struct me_subdevice *subdevice,
747 int *caps)
748{
749 me8254_subdevice_t *instance;
750 PDEBUG("executed.\n");
751 instance = (me8254_subdevice_t *) subdevice;
752 *caps = instance->caps;
753 return ME_ERRNO_SUCCESS;
754}
755
756static int me8254_query_subdevice_caps_args(struct me_subdevice *subdevice,
757 int cap, int *args, int count)
758{
759 PDEBUG("executed.\n");
760
761 if (count != 1) {
762 PERROR("Invalid capability argument count.\n");
763 return ME_ERRNO_INVALID_CAP_ARG_COUNT;
764 }
765
766 if (cap == ME_CAP_CTR_WIDTH) {
767 args[0] = ME8254_CTR_WIDTH;
768 } else {
769 PERROR("Invalid capability.\n");
770 return ME_ERRNO_INVALID_CAP;
771 }
772
773 return ME_ERRNO_SUCCESS;
774}
775
776static uint32_t me1400AB_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
777 unsigned int ctr_idx)
778{
779 switch (me8254_idx) {
780
781 case 0:
782 return (reg_base + ME1400AB_8254_A_0_VAL_REG + ctr_idx);
783
784 default:
785 return (reg_base + ME1400AB_8254_B_0_VAL_REG + ctr_idx);
786 }
787
788 return 0;
789}
790
791static uint32_t me1400AB_get_ctrl_reg(uint32_t reg_base,
792 unsigned int me8254_idx,
793 unsigned int ctr_idx)
794{
795 switch (me8254_idx) {
796 case 0:
797 return (reg_base + ME1400AB_8254_A_CTRL_REG);
798
799 default:
800 return (reg_base + ME1400AB_8254_B_CTRL_REG);
801 }
802
803 return 0;
804}
805
806static uint32_t me1400AB_get_clk_src_reg(uint32_t reg_base,
807 unsigned int me8254_idx,
808 unsigned int ctr_idx)
809{
810 switch (me8254_idx) {
811 case 0:
812 return (reg_base + ME1400AB_CLK_SRC_REG);
813
814 default:
815 return (reg_base + ME1400AB_CLK_SRC_REG);
816 }
817
818 return 0;
819}
820
821static uint32_t me1400CD_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
822 unsigned int ctr_idx)
823{
824 switch (me8254_idx) {
825 case 0:
826 return (reg_base + ME1400C_8254_A_0_VAL_REG + ctr_idx);
827
828 case 1:
829 return (reg_base + ME1400C_8254_B_0_VAL_REG + ctr_idx);
830
831 case 2:
832 return (reg_base + ME1400C_8254_C_0_VAL_REG + ctr_idx);
833
834 case 3:
835 return (reg_base + ME1400C_8254_D_0_VAL_REG + ctr_idx);
836
837 case 4:
838 return (reg_base + ME1400C_8254_E_0_VAL_REG + ctr_idx);
839
840 case 5:
841 return (reg_base + ME1400D_8254_A_0_VAL_REG + ctr_idx);
842
843 case 6:
844 return (reg_base + ME1400D_8254_B_0_VAL_REG + ctr_idx);
845
846 case 7:
847 return (reg_base + ME1400D_8254_C_0_VAL_REG + ctr_idx);
848
849 case 8:
850 return (reg_base + ME1400D_8254_D_0_VAL_REG + ctr_idx);
851
852 default:
853 return (reg_base + ME1400D_8254_E_0_VAL_REG + ctr_idx);
854 }
855
856 return 0;
857}
858
859static uint32_t me1400CD_get_ctrl_reg(uint32_t reg_base,
860 unsigned int me8254_idx,
861 unsigned int ctr_idx)
862{
863 switch (me8254_idx) {
864 case 0:
865 return (reg_base + ME1400C_8254_A_CTRL_REG);
866
867 case 1:
868 return (reg_base + ME1400C_8254_B_CTRL_REG);
869
870 case 2:
871 return (reg_base + ME1400C_8254_C_CTRL_REG);
872
873 case 3:
874 return (reg_base + ME1400C_8254_D_CTRL_REG);
875
876 case 4:
877 return (reg_base + ME1400C_8254_E_CTRL_REG);
878
879 case 5:
880 return (reg_base + ME1400D_8254_A_CTRL_REG);
881
882 case 6:
883 return (reg_base + ME1400D_8254_B_CTRL_REG);
884
885 case 7:
886 return (reg_base + ME1400D_8254_C_CTRL_REG);
887
888 case 8:
889 return (reg_base + ME1400D_8254_D_CTRL_REG);
890
891 default:
892 return (reg_base + ME1400D_8254_E_CTRL_REG);
893 }
894
895 return 0;
896}
897
898static uint32_t me1400CD_get_clk_src_reg(uint32_t reg_base,
899 unsigned int me8254_idx,
900 unsigned int ctr_idx)
901{
902 switch (me8254_idx) {
903 case 0:
904 return (reg_base + ME1400C_CLK_SRC_0_REG);
905
906 case 1:
907 return (reg_base + ME1400C_CLK_SRC_0_REG);
908
909 case 2:
910 return (reg_base + ME1400C_CLK_SRC_1_REG);
911
912 case 3:
913 return (reg_base + ME1400C_CLK_SRC_1_REG);
914
915 case 4:
916 return (reg_base + ME1400C_CLK_SRC_2_REG);
917
918 case 5:
919 return (reg_base + ME1400D_CLK_SRC_0_REG);
920
921 case 6:
922 return (reg_base + ME1400D_CLK_SRC_0_REG);
923
924 case 7:
925 return (reg_base + ME1400D_CLK_SRC_1_REG);
926
927 case 8:
928 return (reg_base + ME1400D_CLK_SRC_1_REG);
929
930 default:
931 return (reg_base + ME1400D_CLK_SRC_2_REG);
932 }
933
934 return 0;
935}
936
937static uint32_t me4600_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
938 unsigned int ctr_idx)
939{
940 return (reg_base + ME4600_8254_0_VAL_REG + ctr_idx);
941}
942
943static uint32_t me4600_get_ctrl_reg(uint32_t reg_base, unsigned int me8254_idx,
944 unsigned int ctr_idx)
945{
946 return (reg_base + ME4600_8254_CTRL_REG);
947}
948
949static uint32_t me8100_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
950 unsigned int ctr_idx)
951{
952 return (reg_base + ME8100_COUNTER_REG_0 + ctr_idx * 2);
953}
954
955static uint32_t me8100_get_ctrl_reg(uint32_t reg_base, unsigned int me8254_idx,
956 unsigned int ctr_idx)
957{
958 return (reg_base + ME8100_COUNTER_CTRL_REG);
959}
960
961me8254_subdevice_t *me8254_constructor(uint32_t device_id,
962 uint32_t reg_base,
963 unsigned int me8254_idx,
964 unsigned int ctr_idx,
965 spinlock_t * ctrl_reg_lock,
966 spinlock_t * clk_src_reg_lock)
967{
968 me8254_subdevice_t *subdevice;
969 int err;
970
971 PDEBUG("executed.\n");
972
973 // Allocate memory for subdevice instance
974 subdevice = kmalloc(sizeof(me8254_subdevice_t), GFP_KERNEL);
975
976 if (!subdevice) {
977 PERROR("Cannot get memory for 8254 instance.\n");
978 return NULL;
979 }
980
981 memset(subdevice, 0, sizeof(me8254_subdevice_t));
982
983 // Check if counter index is out of range
984
985 if (ctr_idx > 2) {
986 PERROR("Counter index is out of range.\n");
987 kfree(subdevice);
988 return NULL;
989 }
990 // Initialize subdevice base class
991 err = me_subdevice_init(&subdevice->base);
992
993 if (err) {
994 PERROR("Cannot initialize subdevice base class instance.\n");
995 kfree(subdevice);
996 return NULL;
997 }
998 // Initialize spin locks.
999 spin_lock_init(&subdevice->subdevice_lock);
1000 subdevice->ctrl_reg_lock = ctrl_reg_lock;
1001 subdevice->clk_src_reg_lock = clk_src_reg_lock;
1002
1003 // Save type of Meilhaus device
1004 subdevice->device_id = device_id;
1005
1006 // Save the indices
1007 subdevice->me8254_idx = me8254_idx;
1008 subdevice->ctr_idx = ctr_idx;
1009
1010 // Do device specific initialization
1011 switch (device_id) {
1012
1013 case PCI_DEVICE_ID_MEILHAUS_ME140A:
1014 case PCI_DEVICE_ID_MEILHAUS_ME14EA:
1015 // Check if 8254 index is out of range
1016 if (me8254_idx > 0) {
1017 PERROR("8254 index is out of range.\n");
1018 me_subdevice_deinit(&subdevice->base);
1019 kfree(subdevice);
1020 return NULL;
1021 }
1022
1023 case PCI_DEVICE_ID_MEILHAUS_ME140B: // Fall through
1024 case PCI_DEVICE_ID_MEILHAUS_ME14EB:
1025 // Check if 8254 index is out of range
1026 if (me8254_idx > 1) {
1027 PERROR("8254 index is out of range.\n");
1028 me_subdevice_deinit(&subdevice->base);
1029 kfree(subdevice);
1030 return NULL;
1031 }
1032 // Initialize the counters capabilities
1033 if (ctr_idx == 0)
1034 subdevice->caps =
1035 ME_CAPS_CTR_CLK_INTERNAL_1MHZ |
1036 ME_CAPS_CTR_CLK_INTERNAL_10MHZ |
1037 ME_CAPS_CTR_CLK_EXTERNAL;
1038 else
1039 subdevice->caps =
1040 ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_EXTERNAL;
1041
1042 // Get the counters registers
1043 subdevice->val_reg =
1044 me1400AB_get_val_reg(reg_base, me8254_idx, ctr_idx);
1045 subdevice->ctrl_reg =
1046 me1400AB_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
1047 subdevice->clk_src_reg =
1048 me1400AB_get_clk_src_reg(reg_base, me8254_idx, ctr_idx);
1049 break;
1050
1051 case PCI_DEVICE_ID_MEILHAUS_ME140C:
1052 // Check if 8254 index is out of range
1053 if (me8254_idx > 4) {
1054 PERROR("8254 index is out of range.\n");
1055 me_subdevice_deinit(&subdevice->base);
1056 kfree(subdevice);
1057 return NULL;
1058 }
1059
1060 case PCI_DEVICE_ID_MEILHAUS_ME140D:
1061 // Check if 8254 index is out of range
1062 if (me8254_idx > 9) {
1063 PERROR("8254 index is out of range.\n");
1064 me_subdevice_deinit(&subdevice->base);
1065 kfree(subdevice);
1066 return NULL;
1067 }
1068 // Initialize the counters capabilities
1069 if (ctr_idx == 0) {
1070 if (me8254_idx == 0)
1071 subdevice->caps =
1072 ME_CAPS_CTR_CLK_PREVIOUS |
1073 ME_CAPS_CTR_CLK_INTERNAL_1MHZ |
1074 ME_CAPS_CTR_CLK_INTERNAL_10MHZ |
1075 ME_CAPS_CTR_CLK_EXTERNAL;
1076 else
1077 subdevice->caps =
1078 ME_CAPS_CTR_CLK_INTERNAL_1MHZ |
1079 ME_CAPS_CTR_CLK_INTERNAL_10MHZ |
1080 ME_CAPS_CTR_CLK_EXTERNAL;
1081 } else
1082 subdevice->caps =
1083 ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_EXTERNAL;
1084
1085 // Get the counters registers
1086 subdevice->val_reg =
1087 me1400CD_get_val_reg(reg_base, me8254_idx, ctr_idx);
1088 subdevice->ctrl_reg =
1089 me1400CD_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
1090 subdevice->clk_src_reg =
1091 me1400CD_get_clk_src_reg(reg_base, me8254_idx, ctr_idx);
1092 break;
1093
1094 case PCI_DEVICE_ID_MEILHAUS_ME4610:
1095 case PCI_DEVICE_ID_MEILHAUS_ME4660:
1096 case PCI_DEVICE_ID_MEILHAUS_ME4660I:
1097 case PCI_DEVICE_ID_MEILHAUS_ME4660S:
1098 case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
1099 case PCI_DEVICE_ID_MEILHAUS_ME4670:
1100 case PCI_DEVICE_ID_MEILHAUS_ME4670I:
1101 case PCI_DEVICE_ID_MEILHAUS_ME4670S:
1102 case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
1103 case PCI_DEVICE_ID_MEILHAUS_ME4680:
1104 case PCI_DEVICE_ID_MEILHAUS_ME4680I:
1105 case PCI_DEVICE_ID_MEILHAUS_ME4680S:
1106 case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
1107 // Check if 8254 index is out of range
1108 if (me8254_idx > 0) {
1109 PERROR("8254 index is out of range.\n");
1110 me_subdevice_deinit(&subdevice->base);
1111 kfree(subdevice);
1112 return NULL;
1113 }
1114 // Initialize the counters capabilities
1115 subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL;
1116
1117 // Get the counters registers
1118 subdevice->val_reg =
1119 me4600_get_val_reg(reg_base, me8254_idx, ctr_idx);
1120 subdevice->ctrl_reg =
1121 me4600_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
1122 subdevice->clk_src_reg = 0; // Not used
1123 break;
1124
1125 case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
1126 case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
1127 // Check if 8254 index is out of range
1128 if (me8254_idx > 0) {
1129 PERROR("8254 index is out of range.\n");
1130 me_subdevice_deinit(&subdevice->base);
1131 kfree(subdevice);
1132 return NULL;
1133 }
1134 // Initialize the counters capabilities
1135 subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL;
1136
1137 // Get the counters registers
1138 subdevice->val_reg =
1139 me8100_get_val_reg(reg_base, me8254_idx, ctr_idx);
1140 subdevice->ctrl_reg =
1141 me8100_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
1142 subdevice->clk_src_reg = 0; // Not used
1143 break;
1144
1145 case PCI_DEVICE_ID_MEILHAUS_ME4650:
1146 case PCI_DEVICE_ID_MEILHAUS_ME1400:
1147 case PCI_DEVICE_ID_MEILHAUS_ME14E0:
1148 PERROR("No 8254 subdevices available for subdevice device.\n");
1149 me_subdevice_deinit(&subdevice->base);
1150 kfree(subdevice);
1151 return NULL;
1152
1153 default:
1154 PERROR("Unknown device type.\n");
1155 me_subdevice_deinit(&subdevice->base);
1156 kfree(subdevice);
1157 return NULL;
1158 }
1159
1160 // Overload subdevice base class methods.
1161 subdevice->base.me_subdevice_io_reset_subdevice =
1162 me8254_io_reset_subdevice;
1163 subdevice->base.me_subdevice_io_single_config = me8254_io_single_config;
1164 subdevice->base.me_subdevice_io_single_read = me8254_io_single_read;
1165 subdevice->base.me_subdevice_io_single_write = me8254_io_single_write;
1166 subdevice->base.me_subdevice_query_number_channels =
1167 me8254_query_number_channels;
1168 subdevice->base.me_subdevice_query_subdevice_type =
1169 me8254_query_subdevice_type;
1170 subdevice->base.me_subdevice_query_subdevice_caps =
1171 me8254_query_subdevice_caps;
1172 subdevice->base.me_subdevice_query_subdevice_caps_args =
1173 me8254_query_subdevice_caps_args;
1174
1175 return subdevice;
1176}
diff --git a/drivers/staging/meilhaus/me8254.h b/drivers/staging/meilhaus/me8254.h
new file mode 100644
index 000000000000..572b7196d5a8
--- /dev/null
+++ b/drivers/staging/meilhaus/me8254.h
@@ -0,0 +1,80 @@
1/**
2 * @file me8254.h
3 *
4 * @brief 8254 counter implementation.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _ME8254_H_
28#define _ME8254_H_
29
30#include "mesubdevice.h"
31#include "meslock.h"
32
33#ifdef __KERNEL__
34
35/**
36 * @brief The 8254 subdevice class.
37 */
38typedef struct me8254_subdevice {
39 /* Inheritance */
40 me_subdevice_t base; /**< The subdevice base class. */
41
42 /* Attributes */
43 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
44
45 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect the control register from concurrent access. */
46 spinlock_t *clk_src_reg_lock; /**< Spin lock to protect the clock source register from concurrent access. */
47
48 uint32_t device_id; /**< The Meilhaus device type carrying the 8254 chip. */
49 int me8254_idx; /**< The index of the 8254 chip on the device. */
50 int ctr_idx; /**< The index of the counter on the 8254 chip. */
51
52 int caps; /**< Holds the device capabilities. */
53
54 unsigned long val_reg; /**< Holds the actual counter value. */
55 unsigned long ctrl_reg; /**< Register to configure the 8254 modes. */
56 unsigned long clk_src_reg; /**< Register to configure the counter connections. */
57} me8254_subdevice_t;
58
59/**
60 * @brief The constructor to generate a 8254 instance.
61 *
62 * @param device_id The kind of Meilhaus device holding the 8254.
63 * @param reg_base The register base address of the device as returned by the PCI BIOS.
64 * @param me8254_idx The index of the 8254 chip on the Meilhaus device.
65 * @param ctr_idx The index of the counter inside a 8254 chip.
66 * @param ctrl_reg_lock Pointer to spin lock protecting the 8254 control register from concurrent access.
67 * @param clk_src_reg_lock Pointer to spin lock protecting the clock source register from concurrent access.
68 *
69 * @return Pointer to new instance on success.\n
70 * NULL on error.
71 */
72me8254_subdevice_t *me8254_constructor(uint32_t device_id,
73 uint32_t reg_base,
74 unsigned int me8254_idx,
75 unsigned int ctr_idx,
76 spinlock_t * ctrl_reg_lock,
77 spinlock_t * clk_src_reg_lock);
78
79#endif
80#endif
diff --git a/drivers/staging/meilhaus/me8254_reg.h b/drivers/staging/meilhaus/me8254_reg.h
new file mode 100644
index 000000000000..7e2c36b46f56
--- /dev/null
+++ b/drivers/staging/meilhaus/me8254_reg.h
@@ -0,0 +1,172 @@
1/**
2 * @file me8254_reg.h
3 *
4 * @brief 8254 counter register definitions.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _ME8254_REG_H_
10#define _ME8254_REG_H_
11
12#ifdef __KERNEL__
13
14/* ME1400 A/B register offsets */
15#define ME1400AB_8254_A_0_VAL_REG 0x0004 /**< Offset of 8254 A counter 0 value register. */
16#define ME1400AB_8254_A_1_VAL_REG 0x0005 /**< Offset of 8254 A counter 1 value register. */
17#define ME1400AB_8254_A_2_VAL_REG 0x0006 /**< Offset of 8254 A counter 2 value register. */
18#define ME1400AB_8254_A_CTRL_REG 0x0007 /**< Offset of 8254 A control register. */
19
20#define ME1400AB_8254_B_0_VAL_REG 0x000C /**< Offset of 8254 B counter 0 value register. */
21#define ME1400AB_8254_B_1_VAL_REG 0x000D /**< Offset of 8254 B counter 1 value register. */
22#define ME1400AB_8254_B_2_VAL_REG 0x000E /**< Offset of 8254 B counter 2 value register. */
23#define ME1400AB_8254_B_CTRL_REG 0x000F /**< Offset of 8254 B control register. */
24
25#define ME1400AB_CLK_SRC_REG 0x0010 /**< Offset of clock source register. */
26
27/* ME1400 C register offsets */
28#define ME1400C_8254_A_0_VAL_REG 0x0004 /**< Offset of 8254 A counter 0 value register. */
29#define ME1400C_8254_A_1_VAL_REG 0x0005 /**< Offset of 8254 A counter 0 value register. */
30#define ME1400C_8254_A_2_VAL_REG 0x0006 /**< Offset of 8254 A counter 0 value register. */
31#define ME1400C_8254_A_CTRL_REG 0x0007 /**< Offset of 8254 A control register. */
32
33#define ME1400C_8254_B_0_VAL_REG 0x000C /**< Offset of 8254 B counter 0 value register. */
34#define ME1400C_8254_B_1_VAL_REG 0x000D /**< Offset of 8254 B counter 0 value register. */
35#define ME1400C_8254_B_2_VAL_REG 0x000E /**< Offset of 8254 B counter 0 value register. */
36#define ME1400C_8254_B_CTRL_REG 0x000F /**< Offset of 8254 B control register. */
37
38#define ME1400C_8254_C_0_VAL_REG 0x0010 /**< Offset of 8254 C counter 0 value register. */
39#define ME1400C_8254_C_1_VAL_REG 0x0011 /**< Offset of 8254 C counter 0 value register. */
40#define ME1400C_8254_C_2_VAL_REG 0x0012 /**< Offset of 8254 C counter 0 value register. */
41#define ME1400C_8254_C_CTRL_REG 0x0013 /**< Offset of 8254 C control register. */
42
43#define ME1400C_8254_D_0_VAL_REG 0x0014 /**< Offset of 8254 D counter 0 value register. */
44#define ME1400C_8254_D_1_VAL_REG 0x0015 /**< Offset of 8254 D counter 0 value register. */
45#define ME1400C_8254_D_2_VAL_REG 0x0016 /**< Offset of 8254 D counter 0 value register. */
46#define ME1400C_8254_D_CTRL_REG 0x0017 /**< Offset of 8254 D control register. */
47
48#define ME1400C_8254_E_0_VAL_REG 0x0018 /**< Offset of 8254 E counter 0 value register. */
49#define ME1400C_8254_E_1_VAL_REG 0x0019 /**< Offset of 8254 E counter 0 value register. */
50#define ME1400C_8254_E_2_VAL_REG 0x001A /**< Offset of 8254 E counter 0 value register. */
51#define ME1400C_8254_E_CTRL_REG 0x001B /**< Offset of 8254 E control register. */
52
53#define ME1400C_CLK_SRC_0_REG 0x001C /**< Offset of clock source register 0. */
54#define ME1400C_CLK_SRC_1_REG 0x001D /**< Offset of clock source register 1. */
55#define ME1400C_CLK_SRC_2_REG 0x001E /**< Offset of clock source register 2. */
56
57/* ME1400 D register offsets */
58#define ME1400D_8254_A_0_VAL_REG 0x0044 /**< Offset of 8254 A counter 0 value register. */
59#define ME1400D_8254_A_1_VAL_REG 0x0045 /**< Offset of 8254 A counter 0 value register. */
60#define ME1400D_8254_A_2_VAL_REG 0x0046 /**< Offset of 8254 A counter 0 value register. */
61#define ME1400D_8254_A_CTRL_REG 0x0047 /**< Offset of 8254 A control register. */
62
63#define ME1400D_8254_B_0_VAL_REG 0x004C /**< Offset of 8254 B counter 0 value register. */
64#define ME1400D_8254_B_1_VAL_REG 0x004D /**< Offset of 8254 B counter 0 value register. */
65#define ME1400D_8254_B_2_VAL_REG 0x004E /**< Offset of 8254 B counter 0 value register. */
66#define ME1400D_8254_B_CTRL_REG 0x004F /**< Offset of 8254 B control register. */
67
68#define ME1400D_8254_C_0_VAL_REG 0x0050 /**< Offset of 8254 C counter 0 value register. */
69#define ME1400D_8254_C_1_VAL_REG 0x0051 /**< Offset of 8254 C counter 0 value register. */
70#define ME1400D_8254_C_2_VAL_REG 0x0052 /**< Offset of 8254 C counter 0 value register. */
71#define ME1400D_8254_C_CTRL_REG 0x0053 /**< Offset of 8254 C control register. */
72
73#define ME1400D_8254_D_0_VAL_REG 0x0054 /**< Offset of 8254 D counter 0 value register. */
74#define ME1400D_8254_D_1_VAL_REG 0x0055 /**< Offset of 8254 D counter 0 value register. */
75#define ME1400D_8254_D_2_VAL_REG 0x0056 /**< Offset of 8254 D counter 0 value register. */
76#define ME1400D_8254_D_CTRL_REG 0x0057 /**< Offset of 8254 D control register. */
77
78#define ME1400D_8254_E_0_VAL_REG 0x0058 /**< Offset of 8254 E counter 0 value register. */
79#define ME1400D_8254_E_1_VAL_REG 0x0059 /**< Offset of 8254 E counter 0 value register. */
80#define ME1400D_8254_E_2_VAL_REG 0x005A /**< Offset of 8254 E counter 0 value register. */
81#define ME1400D_8254_E_CTRL_REG 0x005B /**< Offset of 8254 E control register. */
82
83#define ME1400D_CLK_SRC_0_REG 0x005C /**< Offset of clock source register 0. */
84#define ME1400D_CLK_SRC_1_REG 0x005D /**< Offset of clock source register 1. */
85#define ME1400D_CLK_SRC_2_REG 0x005E /**< Offset of clock source register 2. */
86
87/* ME4600 register offsets */
88#define ME4600_8254_0_VAL_REG 0x0000 /**< Offset of 8254 A counter 0 value register. */
89#define ME4600_8254_1_VAL_REG 0x0001 /**< Offset of 8254 A counter 0 value register. */
90#define ME4600_8254_2_VAL_REG 0x0002 /**< Offset of 8254 A counter 0 value register. */
91#define ME4600_8254_CTRL_REG 0x0003 /**< Offset of 8254 A control register. */
92
93/* Command words for 8254 control register */
94#define ME8254_CTRL_SC0 0x00 /**< Counter 0 selection. */
95#define ME8254_CTRL_SC1 0x40 /**< Counter 1 selection. */
96#define ME8254_CTRL_SC2 0x80 /**< Counter 2 selection. */
97
98#define ME8254_CTRL_TLO 0x00 /**< Counter latching operation. */
99#define ME8254_CTRL_LSB 0x10 /**< Only read LSB. */
100#define ME8254_CTRL_MSB 0x20 /**< Only read MSB. */
101#define ME8254_CTRL_LM 0x30 /**< First read LSB, then MSB. */
102
103#define ME8254_CTRL_M0 0x00 /**< Mode 0 selection. */
104#define ME8254_CTRL_M1 0x02 /**< Mode 1 selection. */
105#define ME8254_CTRL_M2 0x04 /**< Mode 2 selection. */
106#define ME8254_CTRL_M3 0x06 /**< Mode 3 selection. */
107#define ME8254_CTRL_M4 0x08 /**< Mode 4 selection. */
108#define ME8254_CTRL_M5 0x0A /**< Mode 5 selection. */
109
110#define ME8254_CTRL_BIN 0x00 /**< Binary counter. */
111#define ME8254_CTRL_BCD 0x01 /**< BCD counter. */
112
113/* ME-1400 A/B clock source register bits */
114#define ME1400AB_8254_A_0_CLK_SRC_1MHZ (0 << 7) /**< 1MHz clock. */
115#define ME1400AB_8254_A_0_CLK_SRC_10MHZ (1 << 7) /**< 10MHz clock. */
116#define ME1400AB_8254_A_0_CLK_SRC_PIN (0 << 6) /**< CLK 0 to SUB-D. */
117#define ME1400AB_8254_A_0_CLK_SRC_QUARZ (1 << 6) /**< Connect CLK 0 with quarz. */
118
119#define ME1400AB_8254_A_1_CLK_SRC_PIN (0 << 5) /**< CLK 1 to SUB-D. */
120#define ME1400AB_8254_A_1_CLK_SRC_PREV (1 << 5) /**< Connect OUT 0 with CLK 1. */
121
122#define ME1400AB_8254_A_2_CLK_SRC_PIN (0 << 4) /**< CLK 2 to SUB-D. */
123#define ME1400AB_8254_A_2_CLK_SRC_PREV (1 << 4) /**< Connect OUT 1 with CLK 2. */
124
125#define ME1400AB_8254_B_0_CLK_SRC_1MHZ (0 << 3) /**< 1MHz clock. */
126#define ME1400AB_8254_B_0_CLK_SRC_10MHZ (1 << 3) /**< 10MHz clock. */
127#define ME1400AB_8254_B_0_CLK_SRC_PIN (0 << 2) /**< CLK 0 to SUB-D. */
128#define ME1400AB_8254_B_0_CLK_SRC_QUARZ (1 << 2) /**< Connect CLK 0 with quarz. */
129
130#define ME1400AB_8254_B_1_CLK_SRC_PIN (0 << 1) /**< CLK 1 to SUB-D. */
131#define ME1400AB_8254_B_1_CLK_SRC_PREV (1 << 1) /**< Connect OUT 0 with CLK 1. */
132
133#define ME1400AB_8254_B_2_CLK_SRC_PIN (0 << 0) /**< CLK 2 to SUB-D. */
134#define ME1400AB_8254_B_2_CLK_SRC_PREV (1 << 0) /**< Connect OUT 1 with CLK 2. */
135
136/* ME-1400 C/D clock source registers bits */
137#define ME1400CD_8254_ACE_0_CLK_SRC_MASK 0x03 /**< Masks all CLK source bits. */
138#define ME1400CD_8254_ACE_0_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */
139#define ME1400CD_8254_ACE_0_CLK_SRC_1MHZ 0x01 /**< Connect CLK to 1MHz. */
140#define ME1400CD_8254_ACE_0_CLK_SRC_10MHZ 0x02 /**< Connect CLK to 10MHz. */
141#define ME1400CD_8254_ACE_0_CLK_SRC_PREV 0x03 /**< Connect CLK to previous counter output on ME-1400 D extension. */
142
143#define ME1400CD_8254_ACE_1_CLK_SRC_MASK 0x04 /**< Masks all CLK source bits. */
144#define ME1400CD_8254_ACE_1_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */
145#define ME1400CD_8254_ACE_1_CLK_SRC_PREV 0x04 /**< Connect CLK to previous counter output. */
146
147#define ME1400CD_8254_ACE_2_CLK_SRC_MASK 0x08 /**< Masks all CLK source bits. */
148#define ME1400CD_8254_ACE_2_CLK_SRC_PIN 0x00 /**< Connect to SUB-D. */
149#define ME1400CD_8254_ACE_2_CLK_SRC_PREV 0x08 /**< Connect CLK to previous counter output. */
150
151#define ME1400CD_8254_BD_0_CLK_SRC_MASK 0x30 /**< Masks all CLK source bits. */
152#define ME1400CD_8254_BD_0_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */
153#define ME1400CD_8254_BD_0_CLK_SRC_1MHZ 0x10 /**< Connect CLK to 1MHz. */
154#define ME1400CD_8254_BD_0_CLK_SRC_10MHZ 0x20 /**< Connect CLK to 10MHz. */
155#define ME1400CD_8254_BD_0_CLK_SRC_PREV 0x30 /**< Connect CLK to previous counter output. */
156
157#define ME1400CD_8254_BD_1_CLK_SRC_MASK 0x40 /**< Masks all CLK source bits. */
158#define ME1400CD_8254_BD_1_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */
159#define ME1400CD_8254_BD_1_CLK_SRC_PREV 0x40 /**< Connect CLK to previous counter output. */
160
161#define ME1400CD_8254_BD_2_CLK_SRC_MASK 0x80 /**< Masks all CLK source bits. */
162#define ME1400CD_8254_BD_2_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */
163#define ME1400CD_8254_BD_2_CLK_SRC_PREV 0x80 /**< Connect CLK to previous counter output. */
164
165/* ME-8100 counter registers */
166#define ME8100_COUNTER_REG_0 0x18 //(r,w)
167#define ME8100_COUNTER_REG_1 0x1A //(r,w)
168#define ME8100_COUNTER_REG_2 0x1C //(r,w)
169#define ME8100_COUNTER_CTRL_REG 0x1E //(r,w)
170
171#endif
172#endif
diff --git a/drivers/staging/meilhaus/me8255.c b/drivers/staging/meilhaus/me8255.c
new file mode 100644
index 000000000000..180e7f8d2146
--- /dev/null
+++ b/drivers/staging/meilhaus/me8255.c
@@ -0,0 +1,462 @@
1/**
2 * @file me8255.c
3 *
4 * @brief 8255 subdevice instance.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef __KERNEL__
28# define __KERNEL__
29#endif
30
31/*
32 * Includes
33 */
34#include <linux/module.h>
35
36#include <linux/slab.h>
37#include <linux/spinlock.h>
38#include <asm/io.h>
39#include <linux/types.h>
40
41#include "medefines.h"
42#include "meinternal.h"
43#include "meerror.h"
44#include "medebug.h"
45
46#include "me8255_reg.h"
47#include "me8255.h"
48
49/*
50 * Defines
51 */
52
53/*
54 * Functions
55 */
56
57static uint8_t get_mode_from_mirror(uint32_t mirror)
58{
59 PDEBUG("executed.\n");
60
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;
65 } else {
66 return ME8255_MODE_IOO;
67 }
68 } else {
69 if (mirror & ME8255_PORT_2_OUTPUT) {
70 return ME8255_MODE_OIO;
71 } else {
72 return ME8255_MODE_IIO;
73 }
74 }
75 } else {
76 if (mirror & ME8255_PORT_1_OUTPUT) {
77 if (mirror & ME8255_PORT_2_OUTPUT) {
78 return ME8255_MODE_OOI;
79 } else {
80 return ME8255_MODE_IOI;
81 }
82 } else {
83 if (mirror & ME8255_PORT_2_OUTPUT) {
84 return ME8255_MODE_OII;
85 } else {
86 return ME8255_MODE_III;
87 }
88 }
89 }
90}
91
92static int me8255_io_reset_subdevice(struct me_subdevice *subdevice,
93 struct file *filep, int flags)
94{
95 me8255_subdevice_t *instance;
96
97 PDEBUG("executed.\n");
98
99 instance = (me8255_subdevice_t *) subdevice;
100
101 if (flags) {
102 PERROR("Invalid flag specified.\n");
103 return ME_ERRNO_INVALID_FLAGS;
104 }
105
106 ME_SUBDEVICE_ENTER;
107
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),
113 instance->ctrl_reg);
114 spin_unlock(instance->ctrl_reg_lock);
115
116 outb(0, instance->port_reg);
117 spin_unlock(&instance->subdevice_lock);
118
119 ME_SUBDEVICE_EXIT;
120
121 return ME_ERRNO_SUCCESS;
122}
123
124static int me8255_io_single_config(struct me_subdevice *subdevice,
125 struct file *filep,
126 int channel,
127 int single_config,
128 int ref,
129 int trig_chan,
130 int trig_type, int trig_edge, int flags)
131{
132 me8255_subdevice_t *instance;
133 int err = ME_ERRNO_SUCCESS;
134
135 PDEBUG("executed.\n");
136
137 instance = (me8255_subdevice_t *) subdevice;
138
139 if (flags & ~ME_IO_SINGLE_CONFIG_DIO_BYTE) {
140 PERROR("Invalid flag specified.\n");
141 return ME_ERRNO_INVALID_FLAGS;
142 }
143
144 if (channel) {
145 PERROR("Invalid channel.\n");
146 return ME_ERRNO_INVALID_CHANNEL;
147 }
148
149 ME_SUBDEVICE_ENTER;
150
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),
157 instance->ctrl_reg);
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),
164 instance->ctrl_reg);
165 spin_unlock(instance->ctrl_reg_lock);
166 } else {
167 PERROR("Invalid port direction.\n");
168 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
169 }
170 spin_unlock(&instance->subdevice_lock);
171
172 ME_SUBDEVICE_EXIT;
173
174 return err;
175}
176
177static int me8255_io_single_read(struct me_subdevice *subdevice,
178 struct file *filep,
179 int channel,
180 int *value, int time_out, int flags)
181{
182 me8255_subdevice_t *instance;
183 int err = ME_ERRNO_SUCCESS;
184
185 PDEBUG("executed.\n");
186
187 instance = (me8255_subdevice_t *) subdevice;
188
189 ME_SUBDEVICE_ENTER;
190
191 spin_lock(&instance->subdevice_lock);
192 switch (flags) {
193 case ME_IO_SINGLE_TYPE_DIO_BIT:
194 if ((channel >= 0) && (channel < 8)) {
195 *value = inb(instance->port_reg) & (0x1 << channel);
196 } else {
197 PERROR("Invalid bit number.\n");
198 err = ME_ERRNO_INVALID_CHANNEL;
199 }
200 break;
201
202 case ME_IO_SINGLE_NO_FLAGS:
203 case ME_IO_SINGLE_TYPE_DIO_BYTE:
204 if (channel == 0) {
205 *value = inb(instance->port_reg);
206 } else {
207 PERROR("Invalid byte number.\n");
208 err = ME_ERRNO_INVALID_CHANNEL;
209 }
210 break;
211
212 default:
213 PERROR("Invalid flags specified.\n");
214 err = ME_ERRNO_INVALID_FLAGS;
215 }
216 spin_unlock(&instance->subdevice_lock);
217
218 ME_SUBDEVICE_EXIT;
219
220 return err;
221}
222
223static int me8255_io_single_write(struct me_subdevice *subdevice,
224 struct file *filep,
225 int channel,
226 int value, int time_out, int flags)
227{
228 me8255_subdevice_t *instance;
229 uint8_t byte;
230 int err = ME_ERRNO_SUCCESS;
231
232 PDEBUG("executed.\n");
233
234 instance = (me8255_subdevice_t *) subdevice;
235
236 ME_SUBDEVICE_ENTER;
237
238 spin_lock(&instance->subdevice_lock);
239 switch (flags) {
240 case ME_IO_SINGLE_TYPE_DIO_BIT:
241 if ((channel >= 0) && (channel < 8)) {
242 if (*instance->
243 ctrl_reg_mirror & (ME8255_PORT_0_OUTPUT <<
244 instance->dio_idx)) {
245 byte = inb(instance->port_reg);
246
247 if (value)
248 byte |= 0x1 << channel;
249 else
250 byte &= ~(0x1 << channel);
251
252 outb(byte, instance->port_reg);
253 } else {
254 PERROR("Port not in output mode.\n");
255 err = ME_ERRNO_PREVIOUS_CONFIG;
256 }
257 } else {
258 PERROR("Invalid bit number.\n");
259 err = ME_ERRNO_INVALID_CHANNEL;
260 }
261 break;
262
263 case ME_IO_SINGLE_NO_FLAGS:
264 case ME_IO_SINGLE_TYPE_DIO_BYTE:
265 if (channel == 0) {
266 if (*instance->
267 ctrl_reg_mirror & (ME8255_PORT_0_OUTPUT <<
268 instance->dio_idx)) {
269 outb(value, instance->port_reg);
270 } else {
271 PERROR("Port not in output mode.\n");
272 err = ME_ERRNO_PREVIOUS_CONFIG;
273 }
274 } else {
275 PERROR("Invalid byte number.\n");
276 err = ME_ERRNO_INVALID_CHANNEL;
277 }
278 break;
279
280 default:
281 PERROR("Invalid flags specified.\n");
282 err = ME_ERRNO_INVALID_FLAGS;
283 }
284 spin_unlock(&instance->subdevice_lock);
285
286 ME_SUBDEVICE_EXIT;
287
288 return err;
289}
290
291static int me8255_query_number_channels(struct me_subdevice *subdevice,
292 int *number)
293{
294 PDEBUG("executed.\n");
295 *number = ME8255_NUMBER_CHANNELS;
296 return ME_ERRNO_SUCCESS;
297}
298
299static int me8255_query_subdevice_type(struct me_subdevice *subdevice,
300 int *type, int *subtype)
301{
302 PDEBUG("executed.\n");
303 *type = ME_TYPE_DIO;
304 *subtype = ME_SUBTYPE_SINGLE;
305 return ME_ERRNO_SUCCESS;
306}
307
308static int me8255_query_subdevice_caps(struct me_subdevice *subdevice,
309 int *caps)
310{
311 PDEBUG("executed.\n");
312 *caps = ME_CAPS_DIO_DIR_BYTE;
313 return ME_ERRNO_SUCCESS;
314}
315
316me8255_subdevice_t *me8255_constructor(uint32_t device_id,
317 uint32_t reg_base,
318 unsigned int me8255_idx,
319 unsigned int dio_idx,
320 int *ctrl_reg_mirror,
321 spinlock_t * ctrl_reg_lock)
322{
323 me8255_subdevice_t *subdevice;
324 int err;
325
326 PDEBUG("executed.\n");
327
328 /* Allocate memory for subdevice instance */
329 subdevice = kmalloc(sizeof(me8255_subdevice_t), GFP_KERNEL);
330
331 if (!subdevice) {
332 PERROR("Cannot get memory for 8255 instance.\n");
333 return NULL;
334 }
335
336 memset(subdevice, 0, sizeof(me8255_subdevice_t));
337
338 /* Check if counter index is out of range */
339
340 if (dio_idx > 2) {
341 PERROR("DIO index is out of range.\n");
342 kfree(subdevice);
343 return NULL;
344 }
345
346 /* Initialize subdevice base class */
347 err = me_subdevice_init(&subdevice->base);
348
349 if (err) {
350 PERROR("Cannot initialize subdevice base class instance.\n");
351 kfree(subdevice);
352 return NULL;
353 }
354 // Initialize spin locks.
355 spin_lock_init(&subdevice->subdevice_lock);
356
357 subdevice->ctrl_reg_lock = ctrl_reg_lock;
358
359 /* Save the pointer to global port settings */
360 subdevice->ctrl_reg_mirror = ctrl_reg_mirror;
361
362 /* Save type of Meilhaus device */
363 subdevice->device_id = device_id;
364
365 /* Save the indices */
366 subdevice->me8255_idx = me8255_idx;
367 subdevice->dio_idx = dio_idx;
368
369 /* Do device specific initialization */
370 switch (device_id) {
371 case PCI_DEVICE_ID_MEILHAUS_ME1400:
372 case PCI_DEVICE_ID_MEILHAUS_ME14E0:
373
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);
380 kfree(subdevice);
381 return NULL;
382 }
383
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);
390 kfree(subdevice);
391 return NULL;
392 }
393
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;
403 }
404
405 break;
406
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);
412 kfree(subdevice);
413 return NULL;
414 }
415
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);
421 kfree(subdevice);
422 return NULL;
423 }
424
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;
434 }
435
436 break;
437
438 default:
439 PERROR("Unknown device type. dev ID: 0x%04x\n", device_id);
440
441 me_subdevice_deinit(&subdevice->base);
442
443 kfree(subdevice);
444
445 return NULL;
446 }
447
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;
460
461 return subdevice;
462}
diff --git a/drivers/staging/meilhaus/me8255.h b/drivers/staging/meilhaus/me8255.h
new file mode 100644
index 000000000000..338230052b3c
--- /dev/null
+++ b/drivers/staging/meilhaus/me8255.h
@@ -0,0 +1,59 @@
1/**
2 * @file me8255.h
3 *
4 * @brief Meilhaus PIO 8255 implementation.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _ME8255_H_
10#define _ME8255_H_
11
12#include "mesubdevice.h"
13#include "meslock.h"
14
15#ifdef __KERNEL__
16
17/**
18 * @brief The 8255 subdevice class.
19 */
20typedef struct me8255_subdevice {
21 /* Inheritance */
22 me_subdevice_t base; /**< The subdevice base class. */
23
24 /* Attributes */
25 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
26
27 int *ctrl_reg_mirror; /**< Pointer to mirror of the control register. */
28 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg and #ctrl_reg_mirror from concurrent access. */
29
30 uint32_t device_id; /**< The PCI device id of the device holding the 8255 chip. */
31 int me8255_idx; /**< The index of the 8255 chip on the device. */
32 int dio_idx; /**< The index of the DIO port on the 8255 chip. */
33
34 unsigned long port_reg; /**< Register to read or write a value from or to the port respectively. */
35 unsigned long ctrl_reg; /**< Register to configure the 8255 modes. */
36} me8255_subdevice_t;
37
38/**
39 * @brief The constructor to generate a 8255 instance.
40 *
41 * @param device_id The kind of Meilhaus device holding the 8255.
42 * @param reg_base The register base address of the device as returned by the PCI BIOS.
43 * @param me8255_idx The index of the 8255 chip on the Meilhaus device.
44 * @param dio_idx The index of the counter inside a 8255 chip.
45 * @param ctr_reg_mirror Pointer to mirror of control register.
46 * @param ctrl_reg_lock Pointer to spin lock protecting the 8255 control register and #ctrl_reg_mirror from concurrent access.
47 *
48 * @return Pointer to new instance on success.\n
49 * NULL on error.
50 */
51me8255_subdevice_t *me8255_constructor(uint32_t device_id,
52 uint32_t reg_base,
53 unsigned int me8255_idx,
54 unsigned int dio_idx,
55 int *ctrl_reg_mirror,
56 spinlock_t * ctrl_reg_lock);
57
58#endif
59#endif
diff --git a/drivers/staging/meilhaus/me8255_reg.h b/drivers/staging/meilhaus/me8255_reg.h
new file mode 100644
index 000000000000..d1dea1a447f6
--- /dev/null
+++ b/drivers/staging/meilhaus/me8255_reg.h
@@ -0,0 +1,50 @@
1/**
2 * @file me8255_reg.h
3 *
4 * @brief 8255 counter register definitions.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _ME8255_REG_H_
10#define _ME8255_REG_H_
11
12#ifdef __KERNEL__
13
14#define ME8255_NUMBER_CHANNELS 8 /**< The number of channels per 8255 port. */
15
16#define ME1400AB_PORT_A_0 0x0000 /**< Port 0 offset. */
17#define ME1400AB_PORT_A_1 0x0001 /**< Port 1 offset. */
18#define ME1400AB_PORT_A_2 0x0002 /**< Port 2 offset. */
19#define ME1400AB_PORT_A_CTRL 0x0003 /**< Control register for 8255 A. */
20
21#define ME1400AB_PORT_B_0 0x0008 /**< Port 0 offset. */
22#define ME1400AB_PORT_B_1 0x0009 /**< Port 1 offset. */
23#define ME1400AB_PORT_B_2 0x000A /**< Port 2 offset. */
24#define ME1400AB_PORT_B_CTRL 0x000B /**< Control register for 8255 B. */
25
26#define ME1400CD_PORT_A_0 0x0000 /**< Port 0 offset. */
27#define ME1400CD_PORT_A_1 0x0001 /**< Port 1 offset. */
28#define ME1400CD_PORT_A_2 0x0002 /**< Port 2 offset. */
29#define ME1400CD_PORT_A_CTRL 0x0003 /**< Control register for 8255 A. */
30
31#define ME1400CD_PORT_B_0 0x0040 /**< Port 0 offset. */
32#define ME1400CD_PORT_B_1 0x0041 /**< Port 1 offset. */
33#define ME1400CD_PORT_B_2 0x0042 /**< Port 2 offset. */
34#define ME1400CD_PORT_B_CTRL 0x0043 /**< Control register for 8255 B. */
35
36#define ME8255_MODE_OOO 0x80 /**< Port 2 = Output, Port 1 = Output, Port 0 = Output */
37#define ME8255_MODE_IOO 0x89 /**< Port 2 = Input, Port 1 = Output, Port 0 = Output */
38#define ME8255_MODE_OIO 0x82 /**< Port 2 = Output, Port 1 = Input, Port 0 = Output */
39#define ME8255_MODE_IIO 0x8B /**< Port 2 = Input, Port 1 = Input, Port 0 = Output */
40#define ME8255_MODE_OOI 0x90 /**< Port 2 = Output, Port 1 = Output, Port 0 = Input */
41#define ME8255_MODE_IOI 0x99 /**< Port 2 = Input, Port 1 = Output, Port 0 = Input */
42#define ME8255_MODE_OII 0x92 /**< Port 2 = Output, Port 1 = Input, Port 0 = Input */
43#define ME8255_MODE_III 0x9B /**< Port 2 = Input, Port 1 = Input, Port 0 = Input */
44
45#define ME8255_PORT_0_OUTPUT 0x1 /**< If set in mirror then port 0 is in output mode. */
46#define ME8255_PORT_1_OUTPUT 0x2 /**< If set in mirror then port 1 is in output mode. */
47#define ME8255_PORT_2_OUTPUT 0x4 /**< If set in mirror then port 2 is in output mode. */
48
49#endif
50#endif
diff --git a/drivers/staging/meilhaus/mecirc_buf.h b/drivers/staging/meilhaus/mecirc_buf.h
new file mode 100644
index 000000000000..e9b591eaa349
--- /dev/null
+++ b/drivers/staging/meilhaus/mecirc_buf.h
@@ -0,0 +1,131 @@
1/**
2 * @file mecirc_buf.h
3 *
4 * @brief Meilhaus circular buffer implementation.
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 _MECIRC_BUF_H_
29#define _MECIRC_BUF_H_
30
31# ifdef __KERNEL__
32
33# ifdef BOSCH
34
35typedef struct me_circ_buf {
36 unsigned int mask;
37// unsigned int count;
38 uint32_t *buf;
39 int volatile head;
40 int volatile tail;
41} me_circ_buf_t;
42
43static int inline me_circ_buf_values(me_circ_buf_t * buf)
44{
45// return ((buf->head - buf->tail) & (buf->count - 1));
46 return ((buf->head - buf->tail) & (buf->mask));
47}
48
49static int inline me_circ_buf_space(me_circ_buf_t * buf)
50{
51// return ((buf->tail - (buf->head + 1)) & (buf->count - 1));
52 return ((buf->tail - (buf->head + 1)) & (buf->mask));
53}
54
55static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
56{
57 int end;
58 int n;
59// end = buf->count - buf->tail;
60// n = (buf->head + end) & (buf->count - 1);
61 end = buf->mask + 1 - buf->tail;
62 n = (buf->head + end) & (buf->mask);
63 return (n < end) ? n : end;
64}
65
66static int inline me_circ_buf_space_to_end(me_circ_buf_t * buf)
67{
68 int end;
69 int n;
70
71// end = buf->count - 1 - buf->head;
72// n = (end + buf->tail) & (buf->count - 1);
73 end = buf->mask - buf->head;
74 n = (end + buf->tail) & (buf->mask);
75 return (n <= end) ? n : (end + 1);
76}
77
78#define _CBUFF_32b_t
79
80# else //~BOSCH
81/// @note buf->mask = buf->count-1 = ME4600_AI_CIRC_BUF_COUNT-1
82
83# ifdef _CBUFF_32b_t
84 //32 bit
85typedef struct me_circ_buf_32b {
86 int volatile head;
87 int volatile tail;
88 unsigned int mask; //buffor size-1 must be 2^n-1 to work
89 uint32_t *buf;
90} me_circ_buf_t;
91# else
92 //16 bit
93typedef struct me_circ_buf_16b {
94 int volatile head;
95 int volatile tail;
96 unsigned int mask; //buffor size-1 must be 2^n-1 to work
97 uint16_t *buf;
98} me_circ_buf_t;
99# endif //_CBUFF_32b_t
100
101/** How many values is in buffer */
102static int inline me_circ_buf_values(me_circ_buf_t * buf)
103{
104 return ((buf->head - buf->tail) & (buf->mask));
105}
106
107/** How many space left */
108static int inline me_circ_buf_space(me_circ_buf_t * buf)
109{
110 return ((buf->tail - (buf->head + 1)) & (buf->mask));
111}
112
113/** How many values can be read from buffor in one chunck. */
114static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
115{
116 return (buf->tail <=
117 buf->head) ? (buf->head - buf->tail) : (buf->mask - buf->tail +
118 1);
119}
120
121/** How many values can be write to buffer in one chunck. */
122static int inline me_circ_buf_space_to_end(me_circ_buf_t * buf)
123{
124 return (buf->tail <=
125 buf->head) ? (buf->mask - buf->head + 1) : (buf->tail -
126 buf->head - 1);
127}
128
129# endif //BOSCH
130# endif //__KERNEL__
131#endif //_MECIRC_BUF_H_
diff --git a/drivers/staging/meilhaus/mecommon.h b/drivers/staging/meilhaus/mecommon.h
new file mode 100644
index 000000000000..ef47c384e018
--- /dev/null
+++ b/drivers/staging/meilhaus/mecommon.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File :mecommon.h
5 * Author :GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
6 * Author :KG (Krzysztof Gantzke) <k.gantzke@meilhaus.de>
7 */
8
9#ifndef _MECOMMON_H_
10#define _MECOMMON_H_
11
12/*==================================================================
13 The version of this release
14 ================================================================*/
15
16#ifndef ME_VERSION_DRIVER
17/* Unknown version */
18# define ME_VERSION_DRIVER 0xFFFFFFFF
19#endif
20
21#ifndef LIBMEDRIVER_VERSION
22/* Unknown version */
23# define LIBMEDRIVER_VERSION 0xFFFFFFFF
24#endif
25
26#endif
diff --git a/drivers/staging/meilhaus/medebug.h b/drivers/staging/meilhaus/medebug.h
new file mode 100644
index 000000000000..382d00fe311d
--- /dev/null
+++ b/drivers/staging/meilhaus/medebug.h
@@ -0,0 +1,125 @@
1/**
2 * @file medebug.h
3 *
4 * @brief Debugging defines.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 * @author Krzysztof Gantzke (k.gantzke@meilhaus.de)
8 */
9
10#ifndef _MEDEBUG_H_
11#define _MEDEBUG_H_
12
13#ifdef __KERNEL__
14
15#include <linux/kernel.h>
16
17//Messages control.
18
19#ifdef MEDEBUG_TEST_ALL /* Switch to enable all info messages. */
20# ifndef MEDEBUG_TEST
21# define MEDEBUG_TEST
22# endif
23# ifndef MEDEBUG_TEST_INFO
24# define MEDEBUG_TEST_INFO
25# endif
26# ifndef MEDEBUG_DEBUG_REG
27# define MEDEBUG_DEBUG_REG /* Switch to enable registry access debuging messages. */
28# endif
29# ifndef MEDEBUG_DEBUG_LOCKS
30# define MEDEBUG_DEBUG_LOCKS /* Switch to enable locking messages. */
31# endif
32#endif
33
34#ifdef MEDEBUG_TEST_INFO /* Switch to enable info and test messages. */
35# ifndef MEDEBUG_INFO
36# define MEDEBUG_INFO /* Switch to enable info messages. */
37# endif
38# ifndef MEDEBUG_TEST
39# define MEDEBUG_TEST
40# endif
41#endif
42
43#ifdef MEDEBUG_TEST /* Switch to enable debug test messages. */
44# ifndef MEDEBUG_DEBUG
45# define MEDEBUG_DEBUG /* Switch to enable debug messages. */
46# endif
47# ifndef MEDEBUG_ERROR
48# define MEDEBUG_ERROR /* Switch to enable error messages. */
49# endif
50#endif
51
52#ifdef MEDEBUG_ERROR /* Switch to enable error messages. */
53# ifndef MEDEBUG_ERROR_CRITICAL /* Also critical error messages. */
54# define MEDEBUG_ERROR_CRITICAL /* Switch to enable high importance error messages. */
55# endif
56#endif
57
58#undef PDEBUG /* Only to be sure. */
59#undef PINFO /* Only to be sure. */
60#undef PERROR /* Only to be sure. */
61#undef PERROR_CRITICAL /* Only to be sure. */
62#undef PDEBUG_REG /* Only to be sure. */
63#undef PDEBUG_LOCKS /* Only to be sure. */
64#undef PSECURITY /* Only to be sure. */
65#undef PLOG /* Only to be sure. */
66
67#ifdef MEDEBUG_DEBUG
68# define PDEBUG(fmt, args...) \
69 printk(KERN_DEBUG"ME_DRV D: <%s> " fmt, __FUNCTION__, ##args)
70#else
71# define PDEBUG(fmt, args...)
72#endif
73
74#ifdef MEDEBUG_DEBUG_LOCKS
75# define PDEBUG_LOCKS(fmt, args...) \
76 printk(KERN_DEBUG"ME_DRV L: <%s> " fmt, __FUNCTION__, ##args)
77#else
78# define PDEBUG_LOCKS(fmt, args...)
79#endif
80
81#ifdef MEDEBUG_DEBUG_REG
82# define PDEBUG_REG(fmt, args...) \
83 printk(KERN_DEBUG"ME_DRV R: <%s:%d> REG:" fmt, __FUNCTION__, __LINE__, ##args)
84#else
85# define PDEBUG_REG(fmt, args...)
86#endif
87
88#ifdef MEDEBUG_INFO
89# define PINFO(fmt, args...) \
90 printk(KERN_INFO"ME_DRV I: " fmt, ##args)
91#else
92# define PINFO(fmt, args...)
93#endif
94
95#ifdef MEDEBUG_ERROR
96# define PERROR(fmt, args...) \
97 printk(KERN_ERR"ME_DRV E: <%s:%i> " fmt, __FILE__, __LINE__, ##args)
98#else
99# define PERROR(fmt, args...)
100#endif
101
102#ifdef MEDEBUG_ERROR_CRITICAL
103# define PERROR_CRITICAL(fmt, args...) \
104 printk(KERN_CRIT"ME_DRV C: <%s:%i> " fmt, __FILE__, __LINE__, ##args)
105#else
106# define PERROR_CRITICAL(fmt, args...)
107#endif
108
109//This debug is only to detect logical errors!
110# define PSECURITY(fmt, args...) \
111 printk(KERN_CRIT"ME_DRV SECURITY: <%s:%s:%i> " fmt, __FILE__, __FUNCTION__, __LINE__, ##args)
112//This debug is to keep track in customers' system
113# define PLOG(fmt, args...) \
114 printk(KERN_INFO"ME_DRV: " fmt, ##args)
115
116//This debug is to check new parts during development
117#ifdef MEDEBUG_DEVELOP
118# define PDEVELOP(fmt, args...) \
119 printk(KERN_CRIT"ME_DRV: <%s:%s:%i> " fmt, __FILE__, __FUNCTION__, __LINE__, ##args)
120#else
121# define PDEVELOP(fmt, args...)
122#endif
123
124#endif //__KERNEL__
125#endif //_MEDEBUG_H_
diff --git a/drivers/staging/meilhaus/medefines.h b/drivers/staging/meilhaus/medefines.h
new file mode 100644
index 000000000000..6158ef5b80e6
--- /dev/null
+++ b/drivers/staging/meilhaus/medefines.h
@@ -0,0 +1,449 @@
1/*
2 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File : medefines.h
5 * Author : GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
6 * Author : KG (Krzysztof Gantzke) <k.gantzke@meilhaus.de>
7 */
8
9#ifndef _MEDEFINES_H_
10#define _MEDEFINES_H_
11
12/*==================================================================
13 General
14 ================================================================*/
15
16#define ME_VALUE_NOT_USED 0x0
17#define ME_VALUE_INVALID ~0x0
18
19/*==================================================================
20 Defines common to access functions
21 ================================================================*/
22
23#define ME_LOCK_RELEASE 0x00010001
24#define ME_LOCK_SET 0x00010002
25#define ME_LOCK_CHECK 0x00010003
26
27/*==================================================================
28 Defines meOpen function
29 ================================================================*/
30
31#define ME_OPEN_NO_FLAGS 0x0
32
33/*==================================================================
34 Defines meClose function
35 ================================================================*/
36
37#define ME_CLOSE_NO_FLAGS 0x0
38
39/*==================================================================
40 Defines meLockDriver function
41 ================================================================*/
42
43#define ME_LOCK_DRIVER_NO_FLAGS 0x0
44
45/*==================================================================
46 Defines meLockDevice function
47 ================================================================*/
48
49#define ME_LOCK_DEVICE_NO_FLAGS 0x0
50
51/*==================================================================
52 Defines meLockSubdevice function
53 ================================================================*/
54
55#define ME_LOCK_SUBDEVICE_NO_FLAGS 0x0
56
57
58/*==================================================================
59 Defines common to error functions
60 ================================================================*/
61
62#define ME_ERROR_MSG_MAX_COUNT 256
63
64#define ME_SWITCH_DISABLE 0x00020001
65#define ME_SWITCH_ENABLE 0x00020002
66
67/*==================================================================
68 Defines common to io functions
69 ================================================================*/
70
71#define ME_REF_DIO_FIFO_LOW 0x00030001
72#define ME_REF_DIO_FIFO_HIGH 0x00030002
73
74#define ME_REF_CTR_PREVIOUS 0x00040001
75#define ME_REF_CTR_INTERNAL_1MHZ 0x00040002
76#define ME_REF_CTR_INTERNAL_10MHZ 0x00040003
77#define ME_REF_CTR_EXTERNAL 0x00040004
78
79#define ME_REF_AI_GROUND 0x00050001
80#define ME_REF_AI_DIFFERENTIAL 0x00050002
81
82#define ME_REF_AO_GROUND 0x00060001
83
84#define ME_TRIG_CHAN_DEFAULT 0x00070001
85#define ME_TRIG_CHAN_SYNCHRONOUS 0x00070002
86
87#define ME_TRIG_TYPE_NONE 0x00000000
88#define ME_TRIG_TYPE_SW 0x00080001
89#define ME_TRIG_TYPE_THRESHOLD 0x00080002
90#define ME_TRIG_TYPE_WINDOW 0x00080003
91#define ME_TRIG_TYPE_EDGE 0x00080004
92#define ME_TRIG_TYPE_SLOPE 0x00080005
93#define ME_TRIG_TYPE_EXT_DIGITAL 0x00080006
94#define ME_TRIG_TYPE_EXT_ANALOG 0x00080007
95#define ME_TRIG_TYPE_PATTERN 0x00080008
96#define ME_TRIG_TYPE_TIMER 0x00080009
97#define ME_TRIG_TYPE_COUNT 0x0008000A
98#define ME_TRIG_TYPE_FOLLOW 0x0008000B
99
100#define ME_TRIG_EDGE_NONE 0x00000000
101#define ME_TRIG_EDGE_ABOVE 0x00090001
102#define ME_TRIG_EDGE_BELOW 0x00090002
103#define ME_TRIG_EDGE_ENTRY 0x00090003
104#define ME_TRIG_EDGE_EXIT 0x00090004
105#define ME_TRIG_EDGE_RISING 0x00090005
106#define ME_TRIG_EDGE_FALLING 0x00090006
107#define ME_TRIG_EDGE_ANY 0x00090007
108
109#define ME_TIMER_ACQ_START 0x000A0001
110#define ME_TIMER_SCAN_START 0x000A0002
111#define ME_TIMER_CONV_START 0x000A0003
112
113/*==================================================================
114 Defines for meIOFrequencyToTicks function
115 ================================================================*/
116
117#define ME_IO_FREQUENCY_TO_TICKS_NO_FLAGS 0x0
118
119/*==================================================================
120 Defines for meIOIrqStart function
121 ================================================================*/
122
123#define ME_IRQ_SOURCE_DIO_PATTERN 0x000B0001
124#define ME_IRQ_SOURCE_DIO_MASK 0x000B0002
125#define ME_IRQ_SOURCE_DIO_LINE 0x000B0003
126#define ME_IRQ_SOURCE_DIO_OVER_TEMP 0x000B0004
127
128#define ME_IRQ_EDGE_NOT_USED 0x00000000
129#define ME_IRQ_EDGE_RISING 0x000C0001
130#define ME_IRQ_EDGE_FALLING 0x000C0002
131#define ME_IRQ_EDGE_ANY 0x000C0003
132
133/*==================================================================
134 Defines for meIOIrqStart function
135 ================================================================*/
136
137#define ME_IO_IRQ_START_NO_FLAGS 0x000000
138#define ME_IO_IRQ_START_DIO_BIT 0x000001
139#define ME_IO_IRQ_START_DIO_BYTE 0x000002
140#define ME_IO_IRQ_START_DIO_WORD 0x000004
141#define ME_IO_IRQ_START_DIO_DWORD 0x000008
142#define ME_IO_IRQ_START_PATTERN_FILTERING 0x000010
143#define ME_IO_IRQ_START_EXTENDED_STATUS 0x000020
144
145/*==================================================================
146 Defines for meIOIrqWait function
147 ================================================================*/
148
149#define ME_IO_IRQ_WAIT_NO_FLAGS 0x000000
150#define ME_IO_IRQ_WAIT_NORMAL_STATUS 0x000001
151#define ME_IO_IRQ_WAIT_EXTENDED_STATUS 0x000002
152
153/*==================================================================
154 Defines for meIOIrqStop function
155 ================================================================*/
156
157#define ME_IO_IRQ_STOP_NO_FLAGS 0x000000
158
159/*==================================================================
160 Defines for meIOIrqSetCallback function
161 ================================================================*/
162
163#define ME_IO_IRQ_SET_CALLBACK_NO_FLAGS 0x0
164
165/*==================================================================
166 Defines for meIOResetDevice function
167 ================================================================*/
168
169#define ME_IO_RESET_DEVICE_NO_FLAGS 0x0
170
171/*==================================================================
172 Defines for meIOResetSubdevice function
173 ================================================================*/
174
175#define ME_IO_RESET_SUBDEVICE_NO_FLAGS 0x0
176
177/*==================================================================
178 Defines for meIOSingleConfig function
179 ================================================================*/
180
181#define ME_SINGLE_CONFIG_DIO_INPUT 0x000D0001
182#define ME_SINGLE_CONFIG_DIO_OUTPUT 0x000D0002
183#define ME_SINGLE_CONFIG_DIO_HIGH_IMPEDANCE 0x000D0003
184#define ME_SINGLE_CONFIG_DIO_SINK 0x000D0004
185#define ME_SINGLE_CONFIG_DIO_SOURCE 0x000D0005
186#define ME_SINGLE_CONFIG_DIO_MUX32M 0x000D0006
187#define ME_SINGLE_CONFIG_DIO_DEMUX32 0x000D0007
188#define ME_SINGLE_CONFIG_DIO_BIT_PATTERN 0x000D0008
189
190#define ME_SINGLE_CONFIG_CTR_8254_MODE_0 0x000E0001
191#define ME_SINGLE_CONFIG_CTR_8254_MODE_1 0x000E0002
192#define ME_SINGLE_CONFIG_CTR_8254_MODE_2 0x000E0003
193#define ME_SINGLE_CONFIG_CTR_8254_MODE_3 0x000E0004
194#define ME_SINGLE_CONFIG_CTR_8254_MODE_4 0x000E0005
195#define ME_SINGLE_CONFIG_CTR_8254_MODE_5 0x000E0006
196
197#define ME_IO_SINGLE_CONFIG_NO_FLAGS 0x00
198#define ME_IO_SINGLE_CONFIG_DIO_BIT 0x01
199#define ME_IO_SINGLE_CONFIG_DIO_BYTE 0x02
200#define ME_IO_SINGLE_CONFIG_DIO_WORD 0x04
201#define ME_IO_SINGLE_CONFIG_DIO_DWORD 0x08
202#define ME_IO_SINGLE_CONFIG_MULTISIG_LED_ON 0x10
203#define ME_IO_SINGLE_CONFIG_MULTISIG_LED_OFF 0x20
204#define ME_IO_SINGLE_CONFIG_AI_RMS 0x40
205#define ME_IO_SINGLE_CONFIG_CONTINUE 0x80
206
207/*==================================================================
208 Defines for meIOSingle function
209 ================================================================*/
210
211#define ME_IO_SINGLE_NO_FLAGS 0x0
212#define ME_IO_SINGLE_NONBLOCKING 0x20
213
214#define ME_DIR_INPUT 0x000F0001
215#define ME_DIR_OUTPUT 0x000F0002
216
217#define ME_IO_SINGLE_TYPE_NO_FLAGS 0x00
218#define ME_IO_SINGLE_TYPE_DIO_BIT 0x01
219#define ME_IO_SINGLE_TYPE_DIO_BYTE 0x02
220#define ME_IO_SINGLE_TYPE_DIO_WORD 0x04
221#define ME_IO_SINGLE_TYPE_DIO_DWORD 0x08
222#define ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS 0x10
223#define ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING 0x20
224
225/*==================================================================
226 Defines for meIOStreamConfig function
227 ================================================================*/
228
229#define ME_IO_STREAM_CONFIG_NO_FLAGS 0x0
230#define ME_IO_STREAM_CONFIG_BIT_PATTERN 0x1
231#define ME_IO_STREAM_CONFIG_WRAPAROUND 0x2
232#define ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD 0x4
233#define ME_IO_STREAM_CONFIG_HARDWARE_ONLY 0x8
234
235#define ME_IO_STREAM_CONFIG_TYPE_NO_FLAGS 0x0
236
237#define ME_IO_STREAM_TRIGGER_TYPE_NO_FLAGS 0x0
238
239/*==================================================================
240 Defines for meIOStreamRead function
241 ================================================================*/
242
243#define ME_READ_MODE_BLOCKING 0x00100001
244#define ME_READ_MODE_NONBLOCKING 0x00100002
245
246#define ME_IO_STREAM_READ_NO_FLAGS 0x0
247#define ME_IO_STREAM_READ_FRAMES 0x1
248
249/*==================================================================
250 Defines for meIOStreamWrite function
251 ================================================================*/
252
253#define ME_WRITE_MODE_BLOCKING 0x00110001
254#define ME_WRITE_MODE_NONBLOCKING 0x00110002
255#define ME_WRITE_MODE_PRELOAD 0x00110003
256
257#define ME_IO_STREAM_WRITE_NO_FLAGS 0x00000000
258
259/*==================================================================
260 Defines for meIOStreamStart function
261 ================================================================*/
262
263#define ME_IO_STREAM_START_NO_FLAGS 0x00000000
264
265#define ME_START_MODE_BLOCKING 0x00120001
266#define ME_START_MODE_NONBLOCKING 0x00120002
267
268#define ME_IO_STREAM_START_TYPE_NO_FLAGS 0x0
269#define ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS 0x1
270
271/*==================================================================
272 Defines for meIOStreamStop function
273 ================================================================*/
274
275#define ME_IO_STREAM_STOP_NO_FLAGS 0x00000000
276#define ME_IO_STREAM_STOP_PRESERVE_BUFFERS 0x00000001
277
278#define ME_STOP_MODE_IMMEDIATE 0x00130001
279#define ME_STOP_MODE_LAST_VALUE 0x00130002
280
281#define ME_IO_STREAM_STOP_TYPE_NO_FLAGS 0x00000000
282
283/*==================================================================
284 Defines for meIOStreamStatus function
285 ================================================================*/
286
287#define ME_WAIT_NONE 0x00140001
288#define ME_WAIT_IDLE 0x00140002
289
290#define ME_STATUS_INVALID 0x00000000
291#define ME_STATUS_IDLE 0x00150001
292#define ME_STATUS_BUSY 0x00150002
293#define ME_STATUS_ERROR 0x00150003
294
295#define ME_IO_STREAM_STATUS_NO_FLAGS 0x00000000
296
297/*==================================================================
298 Defines for meIOStreamSetCallbacks function
299 ================================================================*/
300
301#define ME_IO_STREAM_SET_CALLBACKS_NO_FLAGS 0x00000000
302
303/*==================================================================
304 Defines for meIOStreamNewValues function
305 ================================================================*/
306
307#define ME_IO_STREAM_NEW_VALUES_NO_FLAGS 0x00000000
308
309/*==================================================================
310 Defines for meIOTimeToTicks function
311 ================================================================*/
312
313#define ME_IO_STREAM_TIME_TO_TICKS_NO_FLAGS 0x00000000
314
315/*==================================================================
316 Defines for module types
317 ================================================================*/
318
319#define ME_MODULE_TYPE_MULTISIG_NONE 0x00000000
320#define ME_MODULE_TYPE_MULTISIG_DIFF16_10V 0x00160001
321#define ME_MODULE_TYPE_MULTISIG_DIFF16_20V 0x00160002
322#define ME_MODULE_TYPE_MULTISIG_DIFF16_50V 0x00160003
323#define ME_MODULE_TYPE_MULTISIG_CURRENT16_0_20MA 0x00160004
324#define ME_MODULE_TYPE_MULTISIG_RTD8_PT100 0x00160005
325#define ME_MODULE_TYPE_MULTISIG_RTD8_PT500 0x00160006
326#define ME_MODULE_TYPE_MULTISIG_RTD8_PT1000 0x00160007
327#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_B 0x00160008
328#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_E 0x00160009
329#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_J 0x0016000A
330#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_K 0x0016000B
331#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_N 0x0016000C
332#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_R 0x0016000D
333#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_S 0x0016000E
334#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_T 0x0016000F
335#define ME_MODULE_TYPE_MULTISIG_TE8_TEMP_SENSOR 0x00160010
336
337/*==================================================================
338 Defines for meQuerySubdeviceCaps function
339 ================================================================*/
340
341#define ME_CAPS_NONE 0x00000000
342
343#define ME_CAPS_DIO_DIR_BIT 0x00000001
344#define ME_CAPS_DIO_DIR_BYTE 0x00000002
345#define ME_CAPS_DIO_DIR_WORD 0x00000004
346#define ME_CAPS_DIO_DIR_DWORD 0x00000008
347#define ME_CAPS_DIO_SINK_SOURCE 0x00000010
348#define ME_CAPS_DIO_BIT_PATTERN_IRQ 0x00000020
349#define ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_RISING 0x00000040
350#define ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_FALLING 0x00000080
351#define ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY 0x00000100
352#define ME_CAPS_DIO_OVER_TEMP_IRQ 0x00000200
353
354#define ME_CAPS_CTR_CLK_PREVIOUS 0x00000001
355#define ME_CAPS_CTR_CLK_INTERNAL_1MHZ 0x00000002
356#define ME_CAPS_CTR_CLK_INTERNAL_10MHZ 0x00000004
357#define ME_CAPS_CTR_CLK_EXTERNAL 0x00000008
358
359#define ME_CAPS_AI_TRIG_SYNCHRONOUS 0x00000001
360/// @note Backward compatibility for me1600 in old style.
361#define ME_CAPS_AI_TRIG_SIMULTANEOUS ME_CAPS_AI_TRIG_SYNCHRONOUS
362#define ME_CAPS_AI_FIFO 0x00000002
363#define ME_CAPS_AI_FIFO_THRESHOLD 0x00000004
364
365#define ME_CAPS_AO_TRIG_SYNCHRONOUS 0x00000001
366/// @note Backward compatibility for me1600 in old style.
367#define ME_CAPS_AO_TRIG_SIMULTANEOUS ME_CAPS_AO_TRIG_SYNCHRONOUS
368#define ME_CAPS_AO_FIFO 0x00000002
369#define ME_CAPS_AO_FIFO_THRESHOLD 0x00000004
370
371#define ME_CAPS_EXT_IRQ_EDGE_RISING 0x00000001
372#define ME_CAPS_EXT_IRQ_EDGE_FALLING 0x00000002
373#define ME_CAPS_EXT_IRQ_EDGE_ANY 0x00000004
374
375/*==================================================================
376 Defines for meQuerySubdeviceCapsArgs function
377 ================================================================*/
378
379#define ME_CAP_AI_FIFO_SIZE 0x001D0000
380#define ME_CAP_AI_BUFFER_SIZE 0x001D0001
381
382#define ME_CAP_AO_FIFO_SIZE 0x001F0000
383#define ME_CAP_AO_BUFFER_SIZE 0x001F0001
384
385#define ME_CAP_CTR_WIDTH 0x00200000
386
387/*==================================================================
388 Defines common to query functions
389 ================================================================*/
390
391#define ME_UNIT_INVALID 0x00000000
392#define ME_UNIT_VOLT 0x00170001
393#define ME_UNIT_AMPERE 0x00170002
394#define ME_UNIT_ANY 0x00170003
395
396#define ME_TYPE_INVALID 0x00000000
397#define ME_TYPE_AO 0x00180001
398#define ME_TYPE_AI 0x00180002
399#define ME_TYPE_DIO 0x00180003
400#define ME_TYPE_DO 0x00180004
401#define ME_TYPE_DI 0x00180005
402#define ME_TYPE_CTR 0x00180006
403#define ME_TYPE_EXT_IRQ 0x00180007
404
405#define ME_SUBTYPE_INVALID 0x00000000
406#define ME_SUBTYPE_SINGLE 0x00190001
407#define ME_SUBTYPE_STREAMING 0x00190002
408#define ME_SUBTYPE_CTR_8254 0x00190003
409#define ME_SUBTYPE_ANY 0x00190004
410
411#define ME_DEVICE_DRIVER_NAME_MAX_COUNT 64
412#define ME_DEVICE_NAME_MAX_COUNT 64
413
414#define ME_DEVICE_DESCRIPTION_MAX_COUNT 256
415
416#define ME_BUS_TYPE_INVALID 0x00000000
417#define ME_BUS_TYPE_PCI 0x001A0001
418#define ME_BUS_TYPE_USB 0x001A0002
419
420#define ME_PLUGGED_INVALID 0x00000000
421#define ME_PLUGGED_IN 0x001B0001
422#define ME_PLUGGED_OUT 0x001B0002
423
424#define ME_EXTENSION_TYPE_INVALID 0x00000000
425#define ME_EXTENSION_TYPE_NONE 0x001C0001
426#define ME_EXTENSION_TYPE_MUX32M 0x001C0002
427#define ME_EXTENSION_TYPE_DEMUX32 0x001C0003
428#define ME_EXTENSION_TYPE_MUX32S 0x001C0004
429
430#define ME_ACCESS_TYPE_INVALID 0x00000000
431#define ME_ACCESS_TYPE_LOCAL 0x001D0001
432#define ME_ACCESS_TYPE_REMOTE 0x001D0002
433
434/// @note Add by KG
435
436/*==================================================================
437 Defines for meUtilityPWM
438 ================================================================*/
439#define ME_PWM_START_CONNECT_INTERNAL 0x00200001
440
441/* Flags for SingleConfig channels configure */
442#define ME_SINGLE_CHANNEL_NOT_CONFIGURED 0x00
443#define ME_SINGLE_CHANNEL_CONFIGURED 0x01
444
445/* Define if configuration should be downloaded to driver */
446#define ME_CONFIG_LOAD_NO_FLAGS 0x0
447#define ME_CONFIG_LOAD_TO_DRIVER 0x1
448
449#endif
diff --git a/drivers/staging/meilhaus/medevice.c b/drivers/staging/meilhaus/medevice.c
new file mode 100644
index 000000000000..8f62e16c7a37
--- /dev/null
+++ b/drivers/staging/meilhaus/medevice.c
@@ -0,0 +1,1740 @@
1/**
2 * @file medevice.c
3 *
4 * @brief Meilhaus device base class.
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#include "mecommon.h"
29#include "meinternal.h"
30#include "medefines.h"
31#include "meerror.h"
32
33#include "medebug.h"
34#include "medevice.h"
35
36#ifndef __KERNEL__
37# define __KERNEL__
38#endif
39
40static int me_device_io_irq_start(struct me_device *device,
41 struct file *filep,
42 int subdevice,
43 int channel,
44 int irq_source,
45 int irq_edge, int irq_arg, int flags)
46{
47 int err = ME_ERRNO_SUCCESS;
48 me_subdevice_t *s;
49
50 PDEBUG("executed.\n");
51
52 // Check subdevice index.
53 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
54 PERROR("Invalid subdevice.\n");
55 return ME_ERRNO_INVALID_SUBDEVICE;
56 }
57 // Enter device.
58 err = me_dlock_enter(&device->dlock, filep);
59
60 if (err) {
61 PERROR("Cannot enter device.\n");
62 return err;
63 }
64 // Get subdevice instance.
65 s = me_slist_get_subdevice(&device->slist, subdevice);
66
67 if (s) {
68 // Call subdevice method.
69 err = s->me_subdevice_io_irq_start(s,
70 filep,
71 channel,
72 irq_source,
73 irq_edge, irq_arg, flags);
74 } else {
75 // Something really bad happened.
76 PERROR("Cannot get subdevice instance.\n");
77 err = ME_ERRNO_INTERNAL;
78 }
79
80 // Exit device.
81 me_dlock_exit(&device->dlock, filep);
82
83 return err;
84}
85
86static int me_device_io_irq_wait(struct me_device *device,
87 struct file *filep,
88 int subdevice,
89 int channel,
90 int *irq_count,
91 int *value, int time_out, int flags)
92{
93 int err = ME_ERRNO_SUCCESS;
94 me_subdevice_t *s;
95
96 PDEBUG("executed.\n");
97
98 // Check subdevice index.
99 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
100 PERROR("Invalid subdevice.\n");
101 return ME_ERRNO_INVALID_SUBDEVICE;
102 }
103 // Enter device.
104 err = me_dlock_enter(&device->dlock, filep);
105
106 if (err) {
107 PERROR("Cannot enter device.\n");
108 return err;
109 }
110 // Get subdevice instance.
111 s = me_slist_get_subdevice(&device->slist, subdevice);
112
113 if (s) {
114 // Call subdevice method.
115 err = s->me_subdevice_io_irq_wait(s,
116 filep,
117 channel,
118 irq_count,
119 value, time_out, flags);
120 } else {
121 // Something really bad happened.
122 PERROR("Cannot get subdevice instance.\n");
123 err = ME_ERRNO_INTERNAL;
124 }
125
126 // Exit device.
127 me_dlock_exit(&device->dlock, filep);
128
129 return err;
130}
131
132static int me_device_io_irq_stop(struct me_device *device,
133 struct file *filep,
134 int subdevice, int channel, int flags)
135{
136 int err = ME_ERRNO_SUCCESS;
137 me_subdevice_t *s;
138
139 PDEBUG("executed.\n");
140
141 // Check subdevice index.
142 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
143 PERROR("Invalid subdevice.\n");
144 return ME_ERRNO_INVALID_SUBDEVICE;
145 }
146 // Enter device.
147 err = me_dlock_enter(&device->dlock, filep);
148
149 if (err) {
150 PERROR("Cannot enter device.\n");
151 return err;
152 }
153 // Get subdevice instance.
154 s = me_slist_get_subdevice(&device->slist, subdevice);
155
156 if (s) {
157 // Call subdevice method.
158 err = s->me_subdevice_io_irq_stop(s, filep, channel, flags);
159 } else {
160 // Something really bad happened.
161 PERROR("Cannot get subdevice instance.\n");
162 err = ME_ERRNO_INTERNAL;
163 }
164
165 // Exit device.
166 me_dlock_exit(&device->dlock, filep);
167
168 return err;
169}
170
171static int me_device_io_reset_device(struct me_device *device,
172 struct file *filep, int flags)
173{
174 int err = ME_ERRNO_SUCCESS;
175 me_subdevice_t *s;
176 int i, n;
177
178 PDEBUG("executed.\n");
179
180 /* Get the number of subdevices. */
181 n = me_slist_get_number_subdevices(&device->slist);
182
183 // Enter device.
184 err = me_dlock_enter(&device->dlock, filep);
185
186 if (err) {
187 PERROR("Cannot enter device.\n");
188 return err;
189 }
190
191 /* Reset every subdevice in list. */
192 for (i = 0; i < n; i++) {
193 s = me_slist_get_subdevice(&device->slist, i);
194 err = s->me_subdevice_io_reset_subdevice(s, filep, flags);
195
196 if (err) {
197 PERROR("Cannot reset subdevice.\n");
198 break;
199 }
200 }
201
202 // Exit device.
203 me_dlock_exit(&device->dlock, filep);
204
205 return err;
206}
207
208static int me_device_io_reset_subdevice(struct me_device *device,
209 struct file *filep,
210 int subdevice, int flags)
211{
212 int err = ME_ERRNO_SUCCESS;
213 me_subdevice_t *s;
214
215 PDEBUG("executed.\n");
216
217 // Check subdevice index.
218
219 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
220 PERROR("Invalid subdevice.\n");
221 return ME_ERRNO_INVALID_SUBDEVICE;
222 }
223 // Enter device.
224 err = me_dlock_enter(&device->dlock, filep);
225
226 if (err) {
227 PERROR("Cannot enter device.\n");
228 return err;
229 }
230 // Get subdevice instance.
231 s = me_slist_get_subdevice(&device->slist, subdevice);
232
233 if (s) {
234 // Call subdevice method.
235 err = s->me_subdevice_io_reset_subdevice(s, filep, flags);
236 } else {
237 // Something really bad happened.
238 PERROR("Cannot get subdevice instance.\n");
239 err = ME_ERRNO_INTERNAL;
240 }
241
242 // Exit device.
243 me_dlock_exit(&device->dlock, filep);
244
245 return err;
246}
247
248static int me_device_io_single_config(struct me_device *device,
249 struct file *filep,
250 int subdevice,
251 int channel,
252 int single_config,
253 int ref,
254 int trig_chan,
255 int trig_type, int trig_edge, int flags)
256{
257 int err = ME_ERRNO_SUCCESS;
258 me_subdevice_t *s;
259
260 PDEBUG("executed.\n");
261
262 // Check subdevice index.
263
264 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
265 PERROR("Invalid subdevice.\n");
266 return ME_ERRNO_INVALID_SUBDEVICE;
267 }
268 // Enter device.
269 err = me_dlock_enter(&device->dlock, filep);
270
271 if (err) {
272 PERROR("Cannot enter device.\n");
273 return err;
274 }
275 // Get subdevice instance.
276 s = me_slist_get_subdevice(&device->slist, subdevice);
277
278 if (s) {
279 // Call subdevice method.
280 err = s->me_subdevice_io_single_config(s,
281 filep,
282 channel,
283 single_config,
284 ref,
285 trig_chan,
286 trig_type,
287 trig_edge, flags);
288 } else {
289 // Something really bad happened.
290 PERROR("Cannot get subdevice instance.\n");
291 err = ME_ERRNO_INTERNAL;
292 }
293
294 // Exit device.
295 me_dlock_exit(&device->dlock, filep);
296
297 return err;
298}
299
300static int me_device_io_single_read(struct me_device *device,
301 struct file *filep,
302 int subdevice,
303 int channel,
304 int *value, int time_out, int flags)
305{
306 int err = ME_ERRNO_SUCCESS;
307 me_subdevice_t *s;
308
309 PDEBUG("executed.\n");
310
311 // Check subdevice index.
312
313 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
314 PERROR("Invalid subdevice.\n");
315 return ME_ERRNO_INVALID_SUBDEVICE;
316 }
317 // Enter device.
318 err = me_dlock_enter(&device->dlock, filep);
319
320 if (err) {
321 PERROR("Cannot enter device.\n");
322 return err;
323 }
324 // Get subdevice instance.
325 s = me_slist_get_subdevice(&device->slist, subdevice);
326
327 if (s) {
328 // Call subdevice method.
329 err = s->me_subdevice_io_single_read(s,
330 filep,
331 channel,
332 value, time_out, flags);
333 } else {
334 // Something really bad happened.
335 PERROR("Cannot get subdevice instance.\n");
336 err = ME_ERRNO_INTERNAL;
337 }
338
339 // Exit device.
340 me_dlock_exit(&device->dlock, filep);
341
342 return err;
343}
344
345static int me_device_io_single_write(struct me_device *device,
346 struct file *filep,
347 int subdevice,
348 int channel,
349 int value, int time_out, int flags)
350{
351 int err = ME_ERRNO_SUCCESS;
352 me_subdevice_t *s;
353
354 PDEBUG("executed.\n");
355
356 // Check subdevice index.
357
358 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
359 PERROR("Invalid subdevice.\n");
360 return ME_ERRNO_INVALID_SUBDEVICE;
361 }
362 // Enter device.
363 err = me_dlock_enter(&device->dlock, filep);
364
365 if (err) {
366 PERROR("Cannot enter device.\n");
367 return err;
368 }
369 // Get subdevice instance.
370 s = me_slist_get_subdevice(&device->slist, subdevice);
371
372 if (s) {
373 // Call subdevice method.
374 err = s->me_subdevice_io_single_write(s,
375 filep,
376 channel,
377 value, time_out, flags);
378 } else {
379 // Something really bad happened.
380 PERROR("Cannot get subdevice instance.\n");
381 err = ME_ERRNO_INTERNAL;
382 }
383
384 // Exit device.
385 me_dlock_exit(&device->dlock, filep);
386
387 return err;
388}
389
390static int me_device_io_stream_config(struct me_device *device,
391 struct file *filep,
392 int subdevice,
393 meIOStreamConfig_t * config_list,
394 int count,
395 meIOStreamTrigger_t * trigger,
396 int fifo_irq_threshold, int flags)
397{
398 int err = ME_ERRNO_SUCCESS;
399 me_subdevice_t *s;
400
401 PDEBUG("executed.\n");
402
403 // Check subdevice index.
404
405 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
406 PERROR("Invalid subdevice.\n");
407 return ME_ERRNO_INVALID_SUBDEVICE;
408 }
409 // Enter device.
410 err = me_dlock_enter(&device->dlock, filep);
411
412 if (err) {
413 PERROR("Cannot enter device.\n");
414 return err;
415 }
416 // Get subdevice instance.
417 s = me_slist_get_subdevice(&device->slist, subdevice);
418
419 if (s) {
420 // Call subdevice method.
421 err = s->me_subdevice_io_stream_config(s,
422 filep,
423 config_list,
424 count,
425 trigger,
426 fifo_irq_threshold,
427 flags);
428 } else {
429 // Something really bad happened.
430 PERROR("Cannot get subdevice instance.\n");
431 err = ME_ERRNO_INTERNAL;
432 }
433
434 // Exit device.
435 me_dlock_exit(&device->dlock, filep);
436
437 return err;
438}
439
440static int me_device_io_stream_new_values(struct me_device *device,
441 struct file *filep,
442 int subdevice,
443 int time_out, int *count, int flags)
444{
445 int err = ME_ERRNO_SUCCESS;
446 me_subdevice_t *s;
447
448 PDEBUG("executed.\n");
449
450 // Check subdevice index.
451
452 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
453 PERROR("Invalid subdevice.\n");
454 return ME_ERRNO_INVALID_SUBDEVICE;
455 }
456 // Enter device.
457 err = me_dlock_enter(&device->dlock, filep);
458
459 if (err) {
460 PERROR("Cannot enter device.\n");
461 return err;
462 }
463 // Get subdevice instance.
464 s = me_slist_get_subdevice(&device->slist, subdevice);
465
466 if (s) {
467 // Call subdevice method.
468 err = s->me_subdevice_io_stream_new_values(s,
469 filep,
470 time_out,
471 count, flags);
472 } else {
473 // Something really bad happened.
474 PERROR("Cannot get subdevice instance.\n");
475 err = ME_ERRNO_INTERNAL;
476 }
477
478 // Exit device.
479 me_dlock_exit(&device->dlock, filep);
480
481 return err;
482}
483
484static int me_device_io_stream_read(struct me_device *device,
485 struct file *filep,
486 int subdevice,
487 int read_mode,
488 int *values, int *count, int flags)
489{
490 int err = ME_ERRNO_SUCCESS;
491 me_subdevice_t *s;
492
493 PDEBUG("executed.\n");
494
495 // Check subdevice index.
496
497 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
498 PERROR("Invalid subdevice.\n");
499 return ME_ERRNO_INVALID_SUBDEVICE;
500 }
501 // Enter device.
502 err = me_dlock_enter(&device->dlock, filep);
503
504 if (err) {
505 PERROR("Cannot enter device.\n");
506 return err;
507 }
508 // Get subdevice instance.
509 s = me_slist_get_subdevice(&device->slist, subdevice);
510
511 if (s) {
512 // Call subdevice method.
513 err = s->me_subdevice_io_stream_read(s,
514 filep,
515 read_mode,
516 values, count, flags);
517 } else {
518 // Something really bad happened.
519 PERROR("Cannot get subdevice instance.\n");
520 err = ME_ERRNO_INTERNAL;
521 }
522
523 // Exit device.
524 me_dlock_exit(&device->dlock, filep);
525
526 return err;
527}
528
529static int me_device_io_stream_start(struct me_device *device,
530 struct file *filep,
531 int subdevice,
532 int start_mode, int time_out, int flags)
533{
534 int err = ME_ERRNO_SUCCESS;
535 me_subdevice_t *s;
536
537 PDEBUG("executed.\n");
538
539 // Check subdevice index.
540
541 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
542 PERROR("Invalid subdevice.\n");
543 return ME_ERRNO_INVALID_SUBDEVICE;
544 }
545 // Enter device.
546 err = me_dlock_enter(&device->dlock, filep);
547
548 if (err) {
549 PERROR("Cannot enter device.\n");
550 return err;
551 }
552 // Get subdevice instance.
553 s = me_slist_get_subdevice(&device->slist, subdevice);
554
555 if (s) {
556 // Call subdevice method.
557 err = s->me_subdevice_io_stream_start(s,
558 filep,
559 start_mode,
560 time_out, flags);
561 } else {
562 // Something really bad happened.
563 PERROR("Cannot get subdevice instance.\n");
564 err = ME_ERRNO_INTERNAL;
565 }
566
567 // Exit device.
568 me_dlock_exit(&device->dlock, filep);
569
570 return err;
571}
572
573static int me_device_io_stream_status(struct me_device *device,
574 struct file *filep,
575 int subdevice,
576 int wait,
577 int *status, int *count, int flags)
578{
579 int err = ME_ERRNO_SUCCESS;
580 me_subdevice_t *s;
581
582 PDEBUG("executed.\n");
583
584 // Check subdevice index.
585
586 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
587 PERROR("Invalid subdevice.\n");
588 return ME_ERRNO_INVALID_SUBDEVICE;
589 }
590 // Enter device.
591 err = me_dlock_enter(&device->dlock, filep);
592
593 if (err) {
594 PERROR("Cannot enter device.\n");
595 return err;
596 }
597 // Get subdevice instance.
598 s = me_slist_get_subdevice(&device->slist, subdevice);
599
600 if (s) {
601 // Call subdevice method.
602 err = s->me_subdevice_io_stream_status(s,
603 filep,
604 wait,
605 status, count, flags);
606 } else {
607 // Something really bad happened.
608 PERROR("Cannot get subdevice instance.\n");
609 err = ME_ERRNO_INTERNAL;
610 }
611
612 // Exit device.
613 me_dlock_exit(&device->dlock, filep);
614
615 return err;
616}
617
618static int me_device_io_stream_stop(struct me_device *device,
619 struct file *filep,
620 int subdevice, int stop_mode, int flags)
621{
622 int err = ME_ERRNO_SUCCESS;
623 me_subdevice_t *s;
624
625 PDEBUG("executed.\n");
626
627 // Check subdevice index.
628
629 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
630 PERROR("Invalid subdevice.\n");
631 return ME_ERRNO_INVALID_SUBDEVICE;
632 }
633 // Enter device.
634 err = me_dlock_enter(&device->dlock, filep);
635
636 if (err) {
637 PERROR("Cannot enter device.\n");
638 return err;
639 }
640 // Get subdevice instance.
641 s = me_slist_get_subdevice(&device->slist, subdevice);
642
643 if (s) {
644 // Call subdevice method.
645 err = s->me_subdevice_io_stream_stop(s,
646 filep, stop_mode, flags);
647 } else {
648 // Something really bad happened.
649 PERROR("Cannot get subdevice instance.\n");
650 err = ME_ERRNO_INTERNAL;
651 }
652
653 // Exit device.
654 me_dlock_exit(&device->dlock, filep);
655
656 return err;
657}
658
659static int me_device_io_stream_write(struct me_device *device,
660 struct file *filep,
661 int subdevice,
662 int write_mode,
663 int *values, int *count, int flags)
664{
665 int err = ME_ERRNO_SUCCESS;
666 me_subdevice_t *s;
667
668 PDEBUG("executed.\n");
669
670 // Check subdevice index.
671
672 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
673 PERROR("Invalid subdevice.\n");
674 return ME_ERRNO_INVALID_SUBDEVICE;
675 }
676 // Enter device.
677 err = me_dlock_enter(&device->dlock, filep);
678
679 if (err) {
680 PERROR("Cannot enter device.\n");
681 return err;
682 }
683 // Get subdevice instance.
684 s = me_slist_get_subdevice(&device->slist, subdevice);
685
686 if (s) {
687 // Call subdevice method.
688 err = s->me_subdevice_io_stream_write(s,
689 filep,
690 write_mode,
691 values, count, flags);
692 } else {
693 // Something really bad happened.
694 PERROR("Cannot get subdevice instance.\n");
695 err = ME_ERRNO_INTERNAL;
696 }
697
698 // Exit device.
699 me_dlock_exit(&device->dlock, filep);
700
701 return err;
702}
703
704static int me_device_lock_device(struct me_device *device,
705 struct file *filep, int lock, int flags)
706{
707 PDEBUG("executed.\n");
708
709 return me_dlock_lock(&device->dlock,
710 filep, lock, flags, &device->slist);
711}
712
713static int me_device_lock_subdevice(struct me_device *device,
714 struct file *filep,
715 int subdevice, int lock, int flags)
716{
717 int err = ME_ERRNO_SUCCESS;
718 me_subdevice_t *s;
719
720 PDEBUG("executed.\n");
721
722 // Check subdevice index.
723
724 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
725 PERROR("Invalid subdevice.\n");
726 return ME_ERRNO_INVALID_SUBDEVICE;
727 }
728 // Enter device.
729 err = me_dlock_enter(&device->dlock, filep);
730
731 if (err) {
732 PERROR("Cannot enter device.\n");
733 return err;
734 }
735 // Get subdevice instance.
736 s = me_slist_get_subdevice(&device->slist, subdevice);
737
738 if (s) {
739 // Call subdevice method.
740 err = s->me_subdevice_lock_subdevice(s, filep, lock, flags);
741 } else {
742 // Something really bad happened.
743 PERROR("Cannot get subdevice instance.\n");
744 err = ME_ERRNO_INTERNAL;
745 }
746
747 // Exit device.
748 me_dlock_exit(&device->dlock, filep);
749
750 return err;
751}
752
753static int me_device_query_description_device(struct me_device *device,
754 char **description)
755{
756 PDEBUG("executed.\n");
757 *description = device->device_description;
758 return ME_ERRNO_SUCCESS;
759}
760
761static int me_device_query_info_device(struct me_device *device,
762 int *vendor_id,
763 int *device_id,
764 int *serial_no,
765 int *bus_type,
766 int *bus_no,
767 int *dev_no, int *func_no, int *plugged)
768{
769 PDEBUG("executed.\n");
770
771 if (device->bus_type == ME_BUS_TYPE_PCI) {
772 *vendor_id = device->info.pci.vendor_id;
773 *device_id = device->info.pci.device_id;
774 *serial_no = device->info.pci.serial_no;
775 *bus_type = ME_BUS_TYPE_PCI;
776 *bus_no = device->info.pci.pci_bus_no;
777 *dev_no = device->info.pci.pci_dev_no;
778 *func_no = device->info.pci.pci_func_no;
779 *plugged = ME_PLUGGED_IN;
780 } else {
781 *plugged = ME_PLUGGED_OUT;
782 }
783 return ME_ERRNO_SUCCESS;
784}
785
786static int me_device_query_name_device(struct me_device *device, char **name)
787{
788 PDEBUG("executed.\n");
789 *name = device->device_name;
790 return ME_ERRNO_SUCCESS;
791}
792
793static int me_device_query_name_device_driver(struct me_device *device,
794 char **name)
795{
796 PDEBUG("executed.\n");
797 *name = device->driver_name;
798 return ME_ERRNO_SUCCESS;
799}
800
801static int me_device_query_number_subdevices(struct me_device *device,
802 int *number)
803{
804 PDEBUG("executed.\n");
805 return me_slist_query_number_subdevices(&device->slist, number);
806}
807
808static int me_device_query_number_channels(struct me_device *device,
809 int subdevice, int *number)
810{
811 int err = ME_ERRNO_SUCCESS;
812 me_subdevice_t *s;
813
814 PDEBUG("executed.\n");
815
816 // Check subdevice index.
817
818 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
819 PERROR("Invalid subdevice.\n");
820 return ME_ERRNO_INVALID_SUBDEVICE;
821 }
822 // Get subdevice instance.
823 s = me_slist_get_subdevice(&device->slist, subdevice);
824
825 if (s) {
826 // Call subdevice method.
827 err = s->me_subdevice_query_number_channels(s, number);
828 } else {
829 // Something really bad happened.
830 PERROR("Cannot get subdevice instance.\n");
831 err = ME_ERRNO_INTERNAL;
832 }
833
834 return err;
835}
836
837static int me_device_query_number_ranges(struct me_device *device,
838 int subdevice, int unit, int *count)
839{
840 int err = ME_ERRNO_SUCCESS;
841 me_subdevice_t *s;
842
843 PDEBUG("executed.\n");
844
845 // Check subdevice index.
846
847 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
848 PERROR("Invalid subdevice.\n");
849 return ME_ERRNO_INVALID_SUBDEVICE;
850 }
851 // Get subdevice instance.
852 s = me_slist_get_subdevice(&device->slist, subdevice);
853
854 if (s) {
855 // Call subdevice method.
856 err = s->me_subdevice_query_number_ranges(s, unit, count);
857 } else {
858 // Something really bad happened.
859 PERROR("Cannot get subdevice instance.\n");
860 err = ME_ERRNO_INTERNAL;
861 }
862
863 return err;
864}
865
866static int me_device_query_range_by_min_max(struct me_device *device,
867 int subdevice,
868 int unit,
869 int *min,
870 int *max, int *maxdata, int *range)
871{
872 int err = ME_ERRNO_SUCCESS;
873 me_subdevice_t *s;
874
875 PDEBUG("executed.\n");
876
877 // Check subdevice index.
878
879 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
880 PERROR("Invalid subdevice.\n");
881 return ME_ERRNO_INVALID_SUBDEVICE;
882 }
883 // Get subdevice instance.
884 s = me_slist_get_subdevice(&device->slist, subdevice);
885
886 if (s) {
887 // Call subdevice method.
888 err = s->me_subdevice_query_range_by_min_max(s,
889 unit,
890 min,
891 max,
892 maxdata, range);
893 } else {
894 // Something really bad happened.
895 PERROR("Cannot get subdevice instance.\n");
896 err = ME_ERRNO_INTERNAL;
897 }
898
899 return err;
900}
901
902static int me_device_query_range_info(struct me_device *device,
903 int subdevice,
904 int range,
905 int *unit,
906 int *min, int *max, int *maxdata)
907{
908 int err = ME_ERRNO_SUCCESS;
909 me_subdevice_t *s;
910
911 PDEBUG("executed.\n");
912
913 // Check subdevice index.
914
915 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
916 PERROR("Invalid subdevice.\n");
917 return ME_ERRNO_INVALID_SUBDEVICE;
918 }
919 // Get subdevice instance.
920 s = me_slist_get_subdevice(&device->slist, subdevice);
921
922 if (s) {
923 // Call subdevice method.
924 err = s->me_subdevice_query_range_info(s,
925 range,
926 unit, min, max, maxdata);
927 } else {
928 // Something really bad happened.
929 PERROR("Cannot get subdevice instance.\n");
930 err = ME_ERRNO_INTERNAL;
931 }
932
933 return err;
934}
935
936static int me_device_query_subdevice_by_type(struct me_device *device,
937 int start_subdevice,
938 int type,
939 int subtype, int *subdevice)
940{
941 PDEBUG("executed.\n");
942
943 return me_slist_get_subdevice_by_type(&device->slist,
944 start_subdevice,
945 type, subtype, subdevice);
946}
947
948static int me_device_query_subdevice_type(struct me_device *device,
949 int subdevice,
950 int *type, int *subtype)
951{
952 int err = ME_ERRNO_SUCCESS;
953 me_subdevice_t *s;
954
955 PDEBUG("executed.\n");
956
957 // Check subdevice index.
958
959 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
960 PERROR("Invalid subdevice.\n");
961 return ME_ERRNO_INVALID_SUBDEVICE;
962 }
963 // Get subdevice instance.
964 s = me_slist_get_subdevice(&device->slist, subdevice);
965
966 if (s) {
967 // Call subdevice method.
968 err = s->me_subdevice_query_subdevice_type(s, type, subtype);
969 } else {
970 // Something really bad happened.
971 PERROR("Cannot get subdevice instance.\n");
972 err = ME_ERRNO_INTERNAL;
973 }
974
975 return err;
976}
977
978static int me_device_query_subdevice_caps(struct me_device *device,
979 int subdevice, int *caps)
980{
981 int err = ME_ERRNO_SUCCESS;
982 me_subdevice_t *s;
983
984 PDEBUG("executed.\n");
985
986 // Check subdevice index.
987
988 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
989 PERROR("Invalid subdevice.\n");
990 return ME_ERRNO_INVALID_SUBDEVICE;
991 }
992 // Get subdevice instance.
993 s = me_slist_get_subdevice(&device->slist, subdevice);
994
995 if (s) {
996 // Call subdevice method.
997 err = s->me_subdevice_query_subdevice_caps(s, caps);
998 } else {
999 // Something really bad happened.
1000 PERROR("Cannot get subdevice instance.\n");
1001 err = ME_ERRNO_INTERNAL;
1002 }
1003
1004 return err;
1005}
1006
1007static int me_device_query_subdevice_caps_args(struct me_device *device,
1008 int subdevice,
1009 int cap, int *args, int count)
1010{
1011 int err = ME_ERRNO_SUCCESS;
1012 me_subdevice_t *s;
1013
1014 PDEBUG("executed.\n");
1015
1016 // Check subdevice index.
1017
1018 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
1019 PERROR("Invalid subdevice.\n");
1020 return ME_ERRNO_INVALID_SUBDEVICE;
1021 }
1022 // Get subdevice instance.
1023 s = me_slist_get_subdevice(&device->slist, subdevice);
1024
1025 if (s) {
1026 // Call subdevice method.
1027 err = s->me_subdevice_query_subdevice_caps_args(s,
1028 cap,
1029 args, count);
1030 } else {
1031 // Something really bad happened.
1032 PERROR("Cannot get subdevice instance.\n");
1033 err = ME_ERRNO_INTERNAL;
1034 }
1035
1036 return err;
1037}
1038
1039static int me_device_query_timer(struct me_device *device,
1040 int subdevice,
1041 int timer,
1042 int *base_frequency,
1043 uint64_t * min_ticks, uint64_t * max_ticks)
1044{
1045 int err = ME_ERRNO_SUCCESS;
1046 me_subdevice_t *s;
1047
1048 PDEBUG("executed.\n");
1049
1050 // Check subdevice index.
1051
1052 if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
1053 PERROR("Invalid subdevice.\n");
1054 return ME_ERRNO_INVALID_SUBDEVICE;
1055 }
1056 // Get subdevice instance.
1057 s = me_slist_get_subdevice(&device->slist, subdevice);
1058
1059 if (s) {
1060 // Call subdevice method.
1061 err = s->me_subdevice_query_timer(s,
1062 timer,
1063 base_frequency,
1064 min_ticks, max_ticks);
1065 } else {
1066 // Something really bad happened.
1067 PERROR("Cannot get subdevice instance.\n");
1068 err = ME_ERRNO_INTERNAL;
1069 }
1070
1071 return err;
1072}
1073
1074static int me_device_query_version_device_driver(struct me_device *device,
1075 int *version)
1076/** @todo Versions shold be read from driver. I must overwrite this function in each module. Here should be returned an error!
1077*/
1078{
1079 PDEBUG("executed.\n");
1080 *version = ME_VERSION_DRIVER;
1081 return ME_ERRNO_SUCCESS;
1082}
1083
1084static int me_device_config_load(struct me_device *device, struct file *filep,
1085 me_cfg_device_entry_t * config)
1086{
1087 PDEBUG("executed.\n");
1088 return ME_ERRNO_SUCCESS; //If no need for config return success.
1089// return ME_ERRNO_NOT_SUPPORTED;
1090}
1091
1092static void me_device_destructor(me_device_t * me_device)
1093{
1094 PDEBUG("executed.\n");
1095 me_device_deinit(me_device);
1096 kfree(me_device);
1097}
1098
1099/* //me_device_usb_init
1100int me_device_usb_init(me_device_t *me_device, struct usb_interface *interface)
1101{
1102 PDEBUG("executed.\n");
1103 return -1;
1104}
1105*/
1106
1107static int get_device_descriptions(uint16_t device_id,
1108 char **device_name,
1109 char **device_description,
1110 char **driver_name)
1111/** @todo This is wrong concept! Static table has too strong limitations!
1112* 'device_name' and 'driver_name' should be calculated from 'device_id'
1113* 'device_description' should be read from device or moved to user space and handled by library!
1114*/
1115{
1116 PDEBUG("executed.\n");
1117
1118 switch (device_id) {
1119 case PCI_DEVICE_ID_MEILHAUS_ME1000:
1120 case PCI_DEVICE_ID_MEILHAUS_ME1000_A:
1121 case PCI_DEVICE_ID_MEILHAUS_ME1000_B:
1122 *device_name = ME1000_NAME_DEVICE_ME1000;
1123 *device_description = ME1000_DESCRIPTION_DEVICE_ME1000;
1124 *driver_name = ME1000_NAME_DRIVER;
1125 break;
1126
1127 case PCI_DEVICE_ID_MEILHAUS_ME1400:
1128 *device_name = ME1400_NAME_DEVICE_ME1400;
1129 *device_description = ME1400_DESCRIPTION_DEVICE_ME1400;
1130 *driver_name = ME1400_NAME_DRIVER;
1131 break;
1132
1133 case PCI_DEVICE_ID_MEILHAUS_ME140A:
1134 *device_name = ME1400_NAME_DEVICE_ME1400A;
1135 *device_description = ME1400_DESCRIPTION_DEVICE_ME1400A;
1136 *driver_name = ME1400_NAME_DRIVER;
1137 break;
1138
1139 case PCI_DEVICE_ID_MEILHAUS_ME140B:
1140 *device_name = ME1400_NAME_DEVICE_ME1400B;
1141 *device_description = ME1400_DESCRIPTION_DEVICE_ME1400B;
1142 *driver_name = ME1400_NAME_DRIVER;
1143 break;
1144
1145 case PCI_DEVICE_ID_MEILHAUS_ME14E0:
1146 *device_name = ME1400_NAME_DEVICE_ME1400E;
1147 *device_description = ME1400_DESCRIPTION_DEVICE_ME1400E;
1148 *driver_name = ME1400_NAME_DRIVER;
1149 break;
1150
1151 case PCI_DEVICE_ID_MEILHAUS_ME14EA:
1152 *device_name = ME1400_NAME_DEVICE_ME1400EA;
1153 *device_description = ME1400_DESCRIPTION_DEVICE_ME1400EA;
1154 *driver_name = ME1400_NAME_DRIVER;
1155 break;
1156
1157 case PCI_DEVICE_ID_MEILHAUS_ME14EB:
1158 *device_name = ME1400_NAME_DEVICE_ME1400EB;
1159 *device_description = ME1400_DESCRIPTION_DEVICE_ME1400EB;
1160 *driver_name = ME1400_NAME_DRIVER;
1161 break;
1162
1163 case PCI_DEVICE_ID_MEILHAUS_ME140C:
1164 *device_name = ME1400_NAME_DEVICE_ME1400C;
1165 *device_description = ME1400_DESCRIPTION_DEVICE_ME1400C;
1166 *driver_name = ME1400_NAME_DRIVER;
1167 break;
1168
1169 case PCI_DEVICE_ID_MEILHAUS_ME140D:
1170 *device_name = ME1400_NAME_DEVICE_ME1400D;
1171 *device_description = ME1400_DESCRIPTION_DEVICE_ME1400D;
1172 *driver_name = ME1400_NAME_DRIVER;
1173 break;
1174
1175 case PCI_DEVICE_ID_MEILHAUS_ME1600_4U:
1176 *device_name = ME1600_NAME_DEVICE_ME16004U;
1177 *device_description = ME1600_DESCRIPTION_DEVICE_ME16004U;
1178 *driver_name = ME1600_NAME_DRIVER;
1179 break;
1180
1181 case PCI_DEVICE_ID_MEILHAUS_ME1600_8U:
1182 *device_name = ME1600_NAME_DEVICE_ME16008U;
1183 *device_description = ME1600_DESCRIPTION_DEVICE_ME16008U;
1184 *driver_name = ME1600_NAME_DRIVER;
1185 break;
1186
1187 case PCI_DEVICE_ID_MEILHAUS_ME1600_12U:
1188 *device_name = ME1600_NAME_DEVICE_ME160012U;
1189 *device_description = ME1600_DESCRIPTION_DEVICE_ME160012U;
1190 *driver_name = ME1600_NAME_DRIVER;
1191 break;
1192
1193 case PCI_DEVICE_ID_MEILHAUS_ME1600_16U:
1194 *device_name = ME1600_NAME_DEVICE_ME160016U;
1195 *device_description = ME1600_DESCRIPTION_DEVICE_ME160016U;
1196 *driver_name = ME1600_NAME_DRIVER;
1197 break;
1198
1199 case PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I:
1200 *device_name = ME1600_NAME_DEVICE_ME160016U8I;
1201 *device_description = ME1600_DESCRIPTION_DEVICE_ME160016U8I;
1202 *driver_name = ME1600_NAME_DRIVER;
1203 break;
1204
1205 case PCI_DEVICE_ID_MEILHAUS_ME4610:
1206 *device_name = ME4600_NAME_DEVICE_ME4610;
1207 *device_description = ME4600_DESCRIPTION_DEVICE_ME4610;
1208 *driver_name = ME4600_NAME_DRIVER;
1209 break;
1210
1211 case PCI_DEVICE_ID_MEILHAUS_ME4650:
1212 *device_name = ME4600_NAME_DEVICE_ME4650;
1213 *device_description = ME4600_DESCRIPTION_DEVICE_ME4650;
1214 *driver_name = ME4600_NAME_DRIVER;
1215 break;
1216
1217 case PCI_DEVICE_ID_MEILHAUS_ME4660:
1218 *device_name = ME4600_NAME_DEVICE_ME4660;
1219 *device_description = ME4600_DESCRIPTION_DEVICE_ME4660;
1220 *driver_name = ME4600_NAME_DRIVER;
1221 break;
1222
1223 case PCI_DEVICE_ID_MEILHAUS_ME4660I:
1224 *device_name = ME4600_NAME_DEVICE_ME4660I;
1225 *device_description = ME4600_DESCRIPTION_DEVICE_ME4660I;
1226 *driver_name = ME4600_NAME_DRIVER;
1227 break;
1228
1229 case PCI_DEVICE_ID_MEILHAUS_ME4660S:
1230 *device_name = ME4600_NAME_DEVICE_ME4660S;
1231 *device_description = ME4600_DESCRIPTION_DEVICE_ME4660S;
1232 *driver_name = ME4600_NAME_DRIVER;
1233 break;
1234
1235 case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
1236 *device_name = ME4600_NAME_DEVICE_ME4660IS;
1237 *device_description = ME4600_DESCRIPTION_DEVICE_ME4660IS;
1238 *driver_name = ME4600_NAME_DRIVER;
1239 break;
1240
1241 case PCI_DEVICE_ID_MEILHAUS_ME4670:
1242 *device_name = ME4600_NAME_DEVICE_ME4670;
1243 *device_description = ME4600_DESCRIPTION_DEVICE_ME4670;
1244 *driver_name = ME4600_NAME_DRIVER;
1245 break;
1246
1247 case PCI_DEVICE_ID_MEILHAUS_ME4670I:
1248 *device_name = ME4600_NAME_DEVICE_ME4670I;
1249 *device_description = ME4600_DESCRIPTION_DEVICE_ME4670I;
1250 *driver_name = ME4600_NAME_DRIVER;
1251 break;
1252
1253 case PCI_DEVICE_ID_MEILHAUS_ME4670S:
1254 *device_name = ME4600_NAME_DEVICE_ME4670S;
1255 *device_description = ME4600_DESCRIPTION_DEVICE_ME4670S;
1256 *driver_name = ME4600_NAME_DRIVER;
1257 break;
1258
1259 case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
1260 *device_name = ME4600_NAME_DEVICE_ME4670IS;
1261 *device_description = ME4600_DESCRIPTION_DEVICE_ME4670IS;
1262 *driver_name = ME4600_NAME_DRIVER;
1263 break;
1264
1265 case PCI_DEVICE_ID_MEILHAUS_ME4680:
1266 *device_name = ME4600_NAME_DEVICE_ME4680;
1267 *device_description = ME4600_DESCRIPTION_DEVICE_ME4680;
1268 *driver_name = ME4600_NAME_DRIVER;
1269 break;
1270
1271 case PCI_DEVICE_ID_MEILHAUS_ME4680I:
1272 *device_name = ME4600_NAME_DEVICE_ME4680I;
1273 *device_description = ME4600_DESCRIPTION_DEVICE_ME4680I;
1274 *driver_name = ME4600_NAME_DRIVER;
1275 break;
1276
1277 case PCI_DEVICE_ID_MEILHAUS_ME4680S:
1278 *device_name = ME4600_NAME_DEVICE_ME4680S;
1279 *device_description = ME4600_DESCRIPTION_DEVICE_ME4680S;
1280 *driver_name = ME4600_NAME_DRIVER;
1281 break;
1282
1283 case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
1284 *device_name = ME4600_NAME_DEVICE_ME4680IS;
1285 *device_description = ME4600_DESCRIPTION_DEVICE_ME4680IS;
1286 *driver_name = ME4600_NAME_DRIVER;
1287 break;
1288
1289 case PCI_DEVICE_ID_MEILHAUS_ME6004:
1290 *device_name = ME6000_NAME_DEVICE_ME60004;
1291 *device_description = ME6000_DESCRIPTION_DEVICE_ME60004;
1292 *driver_name = ME6000_NAME_DRIVER;
1293 break;
1294
1295 case PCI_DEVICE_ID_MEILHAUS_ME6008:
1296 *device_name = ME6000_NAME_DEVICE_ME60008;
1297 *device_description = ME6000_DESCRIPTION_DEVICE_ME60008;
1298 *driver_name = ME6000_NAME_DRIVER;
1299 break;
1300
1301 case PCI_DEVICE_ID_MEILHAUS_ME600F:
1302 *device_name = ME6000_NAME_DEVICE_ME600016;
1303 *device_description = ME6000_DESCRIPTION_DEVICE_ME600016;
1304 *driver_name = ME6000_NAME_DRIVER;
1305 break;
1306
1307 case PCI_DEVICE_ID_MEILHAUS_ME6014:
1308 *device_name = ME6000_NAME_DEVICE_ME6000I4;
1309 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I4;
1310 *driver_name = ME6000_NAME_DRIVER;
1311 break;
1312
1313 case PCI_DEVICE_ID_MEILHAUS_ME6018:
1314 *device_name = ME6000_NAME_DEVICE_ME6000I8;
1315 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I8;
1316 *driver_name = ME6000_NAME_DRIVER;
1317 break;
1318
1319 case PCI_DEVICE_ID_MEILHAUS_ME601F:
1320 *device_name = ME6000_NAME_DEVICE_ME6000I16;
1321 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I16;
1322 *driver_name = ME6000_NAME_DRIVER;
1323 break;
1324
1325 case PCI_DEVICE_ID_MEILHAUS_ME6034:
1326 *device_name = ME6000_NAME_DEVICE_ME6000ISLE4;
1327 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4;
1328 *driver_name = ME6000_NAME_DRIVER;
1329 break;
1330
1331 case PCI_DEVICE_ID_MEILHAUS_ME6038:
1332 *device_name = ME6000_NAME_DEVICE_ME6000ISLE8;
1333 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8;
1334 *driver_name = ME6000_NAME_DRIVER;
1335 break;
1336
1337 case PCI_DEVICE_ID_MEILHAUS_ME603F:
1338 *device_name = ME6000_NAME_DEVICE_ME6000ISLE16;
1339 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16;
1340 *driver_name = ME6000_NAME_DRIVER;
1341 break;
1342
1343 case PCI_DEVICE_ID_MEILHAUS_ME6104:
1344 *device_name = ME6000_NAME_DEVICE_ME61004;
1345 *device_description = ME6000_DESCRIPTION_DEVICE_ME61004;
1346 *driver_name = ME6000_NAME_DRIVER;
1347 break;
1348
1349 case PCI_DEVICE_ID_MEILHAUS_ME6108:
1350 *device_name = ME6000_NAME_DEVICE_ME61008;
1351 *device_description = ME6000_DESCRIPTION_DEVICE_ME61008;
1352 *driver_name = ME6000_NAME_DRIVER;
1353 break;
1354
1355 case PCI_DEVICE_ID_MEILHAUS_ME610F:
1356 *device_name = ME6000_NAME_DEVICE_ME610016;
1357 *device_description = ME6000_DESCRIPTION_DEVICE_ME610016;
1358 *driver_name = ME6000_NAME_DRIVER;
1359 break;
1360
1361 case PCI_DEVICE_ID_MEILHAUS_ME6114:
1362 *device_name = ME6000_NAME_DEVICE_ME6100I4;
1363 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I4;
1364 *driver_name = ME6000_NAME_DRIVER;
1365 break;
1366
1367 case PCI_DEVICE_ID_MEILHAUS_ME6118:
1368 *device_name = ME6000_NAME_DEVICE_ME6100I8;
1369 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I8;
1370 *driver_name = ME6000_NAME_DRIVER;
1371 break;
1372
1373 case PCI_DEVICE_ID_MEILHAUS_ME611F:
1374 *device_name = ME6000_NAME_DEVICE_ME6100I16;
1375 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I16;
1376 *driver_name = ME6000_NAME_DRIVER;
1377 break;
1378
1379 case PCI_DEVICE_ID_MEILHAUS_ME6134:
1380 *device_name = ME6000_NAME_DEVICE_ME6100ISLE4;
1381 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4;
1382 *driver_name = ME6000_NAME_DRIVER;
1383 break;
1384
1385 case PCI_DEVICE_ID_MEILHAUS_ME6138:
1386 *device_name = ME6000_NAME_DEVICE_ME6100ISLE8;
1387 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8;
1388 *driver_name = ME6000_NAME_DRIVER;
1389 break;
1390
1391 case PCI_DEVICE_ID_MEILHAUS_ME613F:
1392 *device_name = ME6000_NAME_DEVICE_ME6100ISLE16;
1393 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16;
1394 *driver_name = ME6000_NAME_DRIVER;
1395 break;
1396
1397 case PCI_DEVICE_ID_MEILHAUS_ME6044:
1398 *device_name = ME6000_NAME_DEVICE_ME60004DIO;
1399 *device_description = ME6000_DESCRIPTION_DEVICE_ME60004DIO;
1400 *driver_name = ME6000_NAME_DRIVER;
1401 break;
1402
1403 case PCI_DEVICE_ID_MEILHAUS_ME6048:
1404 *device_name = ME6000_NAME_DEVICE_ME60008DIO;
1405 *device_description = ME6000_DESCRIPTION_DEVICE_ME60008DIO;
1406 *driver_name = ME6000_NAME_DRIVER;
1407 break;
1408
1409 case PCI_DEVICE_ID_MEILHAUS_ME604F:
1410 *device_name = ME6000_NAME_DEVICE_ME600016DIO;
1411 *device_description = ME6000_DESCRIPTION_DEVICE_ME600016DIO;
1412 *driver_name = ME6000_NAME_DRIVER;
1413 break;
1414
1415 case PCI_DEVICE_ID_MEILHAUS_ME6054:
1416 *device_name = ME6000_NAME_DEVICE_ME6000I4DIO;
1417 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I4DIO;
1418 *driver_name = ME6000_NAME_DRIVER;
1419 break;
1420
1421 case PCI_DEVICE_ID_MEILHAUS_ME6058:
1422 *device_name = ME6000_NAME_DEVICE_ME6000I8DIO;
1423 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I8DIO;
1424 *driver_name = ME6000_NAME_DRIVER;
1425 break;
1426
1427 case PCI_DEVICE_ID_MEILHAUS_ME605F:
1428 *device_name = ME6000_NAME_DEVICE_ME6000I16DIO;
1429 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I16DIO;
1430 *driver_name = ME6000_NAME_DRIVER;
1431 break;
1432
1433 case PCI_DEVICE_ID_MEILHAUS_ME6074:
1434 *device_name = ME6000_NAME_DEVICE_ME6000ISLE4DIO;
1435 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4DIO;
1436 *driver_name = ME6000_NAME_DRIVER;
1437 break;
1438
1439 case PCI_DEVICE_ID_MEILHAUS_ME6078:
1440 *device_name = ME6000_NAME_DEVICE_ME6000ISLE8DIO;
1441 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8DIO;
1442 *driver_name = ME6000_NAME_DRIVER;
1443 break;
1444
1445 case PCI_DEVICE_ID_MEILHAUS_ME607F:
1446 *device_name = ME6000_NAME_DEVICE_ME6000ISLE16DIO;
1447 *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16DIO;
1448 *driver_name = ME6000_NAME_DRIVER;
1449 break;
1450
1451 case PCI_DEVICE_ID_MEILHAUS_ME6144:
1452 *device_name = ME6000_NAME_DEVICE_ME61004DIO;
1453 *device_description = ME6000_DESCRIPTION_DEVICE_ME61004DIO;
1454 *driver_name = ME6000_NAME_DRIVER;
1455 break;
1456
1457 case PCI_DEVICE_ID_MEILHAUS_ME6148:
1458 *device_name = ME6000_NAME_DEVICE_ME61008DIO;
1459 *device_description = ME6000_DESCRIPTION_DEVICE_ME61008DIO;
1460 *driver_name = ME6000_NAME_DRIVER;
1461 break;
1462
1463 case PCI_DEVICE_ID_MEILHAUS_ME614F:
1464 *device_name = ME6000_NAME_DEVICE_ME610016DIO;
1465 *device_description = ME6000_DESCRIPTION_DEVICE_ME610016DIO;
1466 *driver_name = ME6000_NAME_DRIVER;
1467 break;
1468
1469 case PCI_DEVICE_ID_MEILHAUS_ME6154:
1470 *device_name = ME6000_NAME_DEVICE_ME6100I4DIO;
1471 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I4DIO;
1472 *driver_name = ME6000_NAME_DRIVER;
1473 break;
1474
1475 case PCI_DEVICE_ID_MEILHAUS_ME6158:
1476 *device_name = ME6000_NAME_DEVICE_ME6100I8DIO;
1477 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I8DIO;
1478 *driver_name = ME6000_NAME_DRIVER;
1479 break;
1480
1481 case PCI_DEVICE_ID_MEILHAUS_ME615F:
1482 *device_name = ME6000_NAME_DEVICE_ME6100I16DIO;
1483 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I16DIO;
1484 *driver_name = ME6000_NAME_DRIVER;
1485 break;
1486
1487 case PCI_DEVICE_ID_MEILHAUS_ME6174:
1488 *device_name = ME6000_NAME_DEVICE_ME6100ISLE4DIO;
1489 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4DIO;
1490 *driver_name = ME6000_NAME_DRIVER;
1491 break;
1492
1493 case PCI_DEVICE_ID_MEILHAUS_ME6178:
1494 *device_name = ME6000_NAME_DEVICE_ME6100ISLE8DIO;
1495 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8DIO;
1496 *driver_name = ME6000_NAME_DRIVER;
1497 break;
1498
1499 case PCI_DEVICE_ID_MEILHAUS_ME617F:
1500 *device_name = ME6000_NAME_DEVICE_ME6100ISLE16DIO;
1501 *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16DIO;
1502 *driver_name = ME6000_NAME_DRIVER;
1503 break;
1504
1505 case PCI_DEVICE_ID_MEILHAUS_ME6259:
1506 *device_name = ME6000_NAME_DEVICE_ME6200I9DIO;
1507 *device_description = ME6000_DESCRIPTION_DEVICE_ME6200I9DIO;
1508 *driver_name = ME6000_NAME_DRIVER;
1509 break;
1510
1511 case PCI_DEVICE_ID_MEILHAUS_ME6359:
1512 *device_name = ME6000_NAME_DEVICE_ME6300I9DIO;
1513 *device_description = ME6000_DESCRIPTION_DEVICE_ME6300I9DIO;
1514 *driver_name = ME6000_NAME_DRIVER;
1515 break;
1516
1517 case PCI_DEVICE_ID_MEILHAUS_ME0630:
1518 *device_name = ME0600_NAME_DEVICE_ME0630;
1519 *device_description = ME0600_DESCRIPTION_DEVICE_ME0630;
1520 *driver_name = ME0600_NAME_DRIVER;
1521 break;
1522
1523 case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
1524 *device_name = ME8100_NAME_DEVICE_ME8100A;
1525 *device_description = ME8100_DESCRIPTION_DEVICE_ME8100A;
1526 *driver_name = ME8100_NAME_DRIVER;
1527 break;
1528
1529 case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
1530 *device_name = ME8100_NAME_DEVICE_ME8100B;
1531 *device_description = ME8100_DESCRIPTION_DEVICE_ME8100B;
1532 *driver_name = ME8100_NAME_DRIVER;
1533 break;
1534
1535 case PCI_DEVICE_ID_MEILHAUS_ME8200_A:
1536 *device_name = ME8200_NAME_DEVICE_ME8200A;
1537 *device_description = ME8200_DESCRIPTION_DEVICE_ME8200A;
1538 *driver_name = ME8200_NAME_DRIVER;
1539 break;
1540
1541 case PCI_DEVICE_ID_MEILHAUS_ME8200_B:
1542 *device_name = ME8200_NAME_DEVICE_ME8200B;
1543 *device_description = ME8200_DESCRIPTION_DEVICE_ME8200B;
1544 *driver_name = ME8200_NAME_DRIVER;
1545 break;
1546
1547 case PCI_DEVICE_ID_MEILHAUS_ME0940:
1548 *device_name = ME0900_NAME_DEVICE_ME0940;
1549 *device_description = ME0900_DESCRIPTION_DEVICE_ME0940;
1550 *driver_name = ME0900_NAME_DRIVER;
1551 break;
1552
1553 case PCI_DEVICE_ID_MEILHAUS_ME0950:
1554 *device_name = ME0900_NAME_DEVICE_ME0950;
1555 *device_description = ME0900_DESCRIPTION_DEVICE_ME0950;
1556 *driver_name = ME0900_NAME_DRIVER;
1557 break;
1558
1559 case PCI_DEVICE_ID_MEILHAUS_ME0960:
1560 *device_name = ME0900_NAME_DEVICE_ME0960;
1561 *device_description = ME0900_DESCRIPTION_DEVICE_ME0960;
1562 *driver_name = ME0900_NAME_DRIVER;
1563 break;
1564/*
1565 case USB_DEVICE_ID_MEPHISTO_S1:
1566 *device_name = MEPHISTO_S1_NAME_DEVICE;
1567 *device_description = MEPHISTO_S1_DESCRIPTION_DEVICE;
1568 *driver_name = MEPHISTO_S1_NAME_DRIVER;
1569 break;
1570*/
1571 default:
1572 *device_name = EMPTY_NAME_DEVICE;
1573 *device_description = EMPTY_DESCRIPTION_DEVICE;
1574 *driver_name = EMPTY_NAME_DRIVER;
1575
1576 PERROR("Invalid device id.\n");
1577
1578 return 1;
1579 }
1580
1581 return 0;
1582}
1583
1584int me_device_pci_init(me_device_t * me_device, struct pci_dev *pci_device)
1585{
1586 int err;
1587 int i;
1588
1589 PDEBUG("executed.\n");
1590
1591 // Initialize device list head.
1592 INIT_LIST_HEAD(&me_device->list);
1593
1594 // Initialize device description strings.
1595 err = get_device_descriptions(pci_device->device,
1596 &me_device->device_name,
1597 &me_device->device_description,
1598 &me_device->driver_name);
1599
1600 if (err) {
1601 PERROR("Cannot initialize device description strings.\n");
1602 return 1;
1603 }
1604 // Enable the pci device.
1605 err = pci_enable_device(pci_device);
1606
1607 if (err < 0) {
1608 PERROR("Cannot enable PCI device.\n");
1609 return 1;
1610 }
1611 // Request the PCI register regions.
1612 err = pci_request_regions(pci_device, me_device->device_name);
1613
1614 if (err < 0) {
1615 PERROR("Cannot request PCI regions.\n");
1616 goto ERROR_0;
1617 }
1618 // The bus carrying the device is a PCI bus.
1619 me_device->bus_type = ME_BUS_TYPE_PCI;
1620
1621 // Store the PCI information for later usage.
1622 me_device->info.pci.pci_device = pci_device;
1623
1624 // Get PCI register bases and sizes.
1625 for (i = 0; i < 6; i++) {
1626 me_device->info.pci.reg_bases[i] =
1627 pci_resource_start(pci_device, i);
1628 me_device->info.pci.reg_sizes[i] =
1629 pci_resource_len(pci_device, i);
1630 }
1631
1632 // Get the PCI location.
1633 me_device->info.pci.pci_bus_no = pci_device->bus->number;
1634 me_device->info.pci.pci_dev_no = PCI_SLOT(pci_device->devfn);
1635 me_device->info.pci.pci_func_no = PCI_FUNC(pci_device->devfn);
1636
1637 // Get Meilhaus specific device information.
1638 me_device->info.pci.vendor_id = pci_device->vendor;
1639 me_device->info.pci.device_id = pci_device->device;
1640 pci_read_config_byte(pci_device, 0x08,
1641 &me_device->info.pci.hw_revision);
1642 pci_read_config_dword(pci_device, 0x2C, &me_device->info.pci.serial_no);
1643
1644 // Get the interrupt request number.
1645 me_device->irq = pci_device->irq;
1646
1647 // Initialize device lock instance.
1648 err = me_dlock_init(&me_device->dlock);
1649
1650 if (err) {
1651 PERROR("Cannot initialize device lock instance.\n");
1652 goto ERROR_1;
1653 }
1654 // Initialize subdevice list instance.
1655 me_slist_init(&me_device->slist);
1656
1657 if (err) {
1658 PERROR("Cannot initialize subdevice list instance.\n");
1659 goto ERROR_2;
1660 }
1661 // Initialize method pointers.
1662 me_device->me_device_io_irq_start = me_device_io_irq_start;
1663 me_device->me_device_io_irq_wait = me_device_io_irq_wait;
1664 me_device->me_device_io_irq_stop = me_device_io_irq_stop;
1665 me_device->me_device_io_reset_device = me_device_io_reset_device;
1666 me_device->me_device_io_reset_subdevice = me_device_io_reset_subdevice;
1667 me_device->me_device_io_single_config = me_device_io_single_config;
1668 me_device->me_device_io_single_read = me_device_io_single_read;
1669 me_device->me_device_io_single_write = me_device_io_single_write;
1670 me_device->me_device_io_stream_config = me_device_io_stream_config;
1671 me_device->me_device_io_stream_new_values =
1672 me_device_io_stream_new_values;
1673 me_device->me_device_io_stream_read = me_device_io_stream_read;
1674 me_device->me_device_io_stream_start = me_device_io_stream_start;
1675 me_device->me_device_io_stream_status = me_device_io_stream_status;
1676 me_device->me_device_io_stream_stop = me_device_io_stream_stop;
1677 me_device->me_device_io_stream_write = me_device_io_stream_write;
1678 me_device->me_device_lock_device = me_device_lock_device;
1679 me_device->me_device_lock_subdevice = me_device_lock_subdevice;
1680 me_device->me_device_query_description_device =
1681 me_device_query_description_device;
1682 me_device->me_device_query_info_device = me_device_query_info_device;
1683 me_device->me_device_query_name_device = me_device_query_name_device;
1684 me_device->me_device_query_name_device_driver =
1685 me_device_query_name_device_driver;
1686 me_device->me_device_query_number_subdevices =
1687 me_device_query_number_subdevices;
1688 me_device->me_device_query_number_channels =
1689 me_device_query_number_channels;
1690 me_device->me_device_query_number_ranges =
1691 me_device_query_number_ranges;
1692 me_device->me_device_query_range_by_min_max =
1693 me_device_query_range_by_min_max;
1694 me_device->me_device_query_range_info = me_device_query_range_info;
1695 me_device->me_device_query_subdevice_by_type =
1696 me_device_query_subdevice_by_type;
1697 me_device->me_device_query_subdevice_type =
1698 me_device_query_subdevice_type;
1699 me_device->me_device_query_subdevice_caps =
1700 me_device_query_subdevice_caps;
1701 me_device->me_device_query_subdevice_caps_args =
1702 me_device_query_subdevice_caps_args;
1703 me_device->me_device_query_timer = me_device_query_timer;
1704 me_device->me_device_query_version_device_driver =
1705 me_device_query_version_device_driver;
1706 me_device->me_device_config_load = me_device_config_load;
1707 me_device->me_device_destructor = me_device_destructor;
1708
1709 return 0;
1710
1711 ERROR_0:
1712 me_dlock_deinit(&me_device->dlock);
1713
1714 ERROR_1:
1715 pci_release_regions(pci_device);
1716
1717 ERROR_2:
1718 pci_disable_device(pci_device);
1719
1720 return 1;
1721}
1722
1723void me_device_deinit(me_device_t * me_device)
1724{
1725 PDEBUG("executed.\n");
1726
1727 me_slist_deinit(&me_device->slist);
1728 me_dlock_deinit(&me_device->dlock);
1729
1730 if (me_device->bus_type == ME_BUS_TYPE_PCI) {
1731 pci_release_regions(me_device->info.pci.pci_device);
1732 pci_disable_device(me_device->info.pci.pci_device);
1733 }
1734/*
1735 else
1736 {
1737 // Must be an USB device.
1738 }
1739*/
1740}
diff --git a/drivers/staging/meilhaus/medevice.h b/drivers/staging/meilhaus/medevice.h
new file mode 100644
index 000000000000..25da82883e1f
--- /dev/null
+++ b/drivers/staging/meilhaus/medevice.h
@@ -0,0 +1,304 @@
1/*
2 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File : medevice.h
5 * Author : GG (Guenter Gebhardt) <support@meilhaus.de>
6 */
7
8#ifndef _MEDEVICE_H_
9#define _MEDEVICE_H_
10
11#ifndef KBUILD_MODNAME
12# define KBUILD_MODNAME KBUILD_STR(memain)
13#endif
14
15#include <linux/pci.h>
16//#include <linux/usb.h>
17#include <linux/fs.h>
18#include <linux/spinlock.h>
19
20#include "metypes.h"
21#include "meslist.h"
22#include "medlock.h"
23
24#ifdef __KERNEL__
25
26/**
27 * @brief Defines a pointer type to a PCI constructor function.
28 */
29typedef struct me_device *(*me_pci_constructor_t) (struct pci_dev *);
30
31/**
32 * @brief Defines a pointer type to a ME-4000 PCI constructor function.
33 */
34#ifdef BOSCH
35typedef struct me_device *(*me_bosch_constructor_t) (struct pci_dev *,
36 int me_bosch_fw);
37#endif
38
39/**
40 * @brief Defines a pointer type to a USB constructor function.
41 */
42//typedef struct me_device *(*me_usb_constructor_t)(struct usb_interface *);
43
44/**
45 * @brief Defines a pointer type to the dummy constructor function.
46 */
47typedef struct me_device *(*me_dummy_constructor_t) (unsigned short vendor_id,
48 unsigned short device_id,
49 unsigned int serial_no,
50 int bus_type,
51 int bus_no,
52 int dev_no, int func_no);
53
54//extern me_usb_constructor_t mephisto_s1_constructor __attribute__ ((weak));
55
56/**
57 * @brief Holds the PCI device information.
58 */
59typedef struct me_pci_info {
60 struct pci_dev *pci_device; /**< Kernel PCI device structure. */
61 uint32_t reg_bases[6]; /**< The base adresses of the PCI bars. */
62 uint32_t reg_sizes[6]; /**< The sizes of the PCI bars. */
63
64 uint32_t pci_bus_no; /**< PCI bus number. */
65 uint32_t pci_dev_no; /**< PCI device number. */
66 uint32_t pci_func_no; /**< PCI function number. */
67
68 uint16_t vendor_id; /**< Meilhaus PCI vendor id. */
69 uint16_t device_id; /**< Meilhaus device id. */
70 uint8_t hw_revision; /**< Hardware revision of the device. */
71 uint32_t serial_no; /**< Serial number of the device. */
72} me_pci_info_t;
73
74/**
75 * @brief Holds the USB device information.
76 */
77//typedef struct me_usb_info {
78//} me_usb_info_t;
79
80/**
81 * @brief The Meilhaus device base class structure.
82 */
83typedef struct me_device {
84 /* Attributes */
85 struct list_head list; /**< Enables the device to be added to a dynamic list. */
86// int magic; /**< The magic number of the structure. */
87
88 int bus_type; /**< The descriminator for the union. */
89 union {
90 me_pci_info_t pci; /**< PCI specific device information. */
91// me_usb_info_t usb; /**< USB specific device information. */
92 } info; /**< Holds the device information. */
93
94 int irq; /**< The irq assigned to this device. */
95
96 me_dlock_t dlock; /**< The device locking structure. */
97 me_slist_t slist; /**< The container holding all subdevices belonging to this device. */
98
99 char *device_name; /**< The name of the Meilhaus device. */
100 char *device_description; /**< The description of the Meilhaus device. */
101 char *driver_name; /**< The name of the device driver module supporting the device family. */
102
103 /* Methods */
104 int (*me_device_io_irq_start) (struct me_device * device,
105 struct file * filep,
106 int subdevice,
107 int channel,
108 int irq_source,
109 int irq_edge, int irq_arg, int flags);
110
111 int (*me_device_io_irq_wait) (struct me_device * device,
112 struct file * filep,
113 int subdevice,
114 int channel,
115 int *irq_count,
116 int *value, int time_out, int flags);
117
118 int (*me_device_io_irq_stop) (struct me_device * device,
119 struct file * filep,
120 int subdevice, int channel, int flags);
121
122 int (*me_device_io_reset_device) (struct me_device * device,
123 struct file * filep, int flags);
124
125 int (*me_device_io_reset_subdevice) (struct me_device * device,
126 struct file * filep,
127 int subdevice, int flags);
128
129 int (*me_device_io_single_config) (struct me_device * device,
130 struct file * filep,
131 int subdevice,
132 int channel,
133 int single_config,
134 int ref,
135 int trig_chan,
136 int trig_type,
137 int trig_edge, int flags);
138
139 int (*me_device_io_single_read) (struct me_device * device,
140 struct file * filep,
141 int subdevice,
142 int channel,
143 int *value, int time_out, int flags);
144
145 int (*me_device_io_single_write) (struct me_device * device,
146 struct file * filep,
147 int subdevice,
148 int channel,
149 int value, int time_out, int flags);
150
151 int (*me_device_io_stream_config) (struct me_device * device,
152 struct file * filep,
153 int subdevice,
154 meIOStreamConfig_t * config_list,
155 int count,
156 meIOStreamTrigger_t * trigger,
157 int fifo_irq_threshold, int flags);
158
159 int (*me_device_io_stream_new_values) (struct me_device * device,
160 struct file * filep,
161 int subdevice,
162 int time_out,
163 int *count, int flags);
164
165 int (*me_device_io_stream_read) (struct me_device * device,
166 struct file * filep,
167 int subdevice,
168 int read_mode,
169 int *values, int *count, int flags);
170
171 int (*me_device_io_stream_start) (struct me_device * device,
172 struct file * filep,
173 int subdevice,
174 int start_mode,
175 int time_out, int flags);
176
177 int (*me_device_io_stream_status) (struct me_device * device,
178 struct file * filep,
179 int subdevice,
180 int wait,
181 int *status, int *count, int flags);
182
183 int (*me_device_io_stream_stop) (struct me_device * device,
184 struct file * filep,
185 int subdevice,
186 int stop_mode, int flags);
187
188 int (*me_device_io_stream_write) (struct me_device * device,
189 struct file * filep,
190 int subdevice,
191 int write_mode,
192 int *values, int *count, int flags);
193
194 int (*me_device_lock_device) (struct me_device * device,
195 struct file * filep, int lock, int flags);
196
197 int (*me_device_lock_subdevice) (struct me_device * device,
198 struct file * filep,
199 int subdevice, int lock, int flags);
200
201 int (*me_device_query_description_device) (struct me_device * device,
202 char **description);
203
204 int (*me_device_query_info_device) (struct me_device * device,
205 int *vendor_id,
206 int *device_id,
207 int *serial_no,
208 int *bus_type,
209 int *bus_no,
210 int *dev_no,
211 int *func_no, int *plugged);
212
213 int (*me_device_query_name_device) (struct me_device * device,
214 char **name);
215
216 int (*me_device_query_name_device_driver) (struct me_device * device,
217 char **name);
218
219 int (*me_device_query_number_subdevices) (struct me_device * device,
220 int *number);
221
222 int (*me_device_query_number_channels) (struct me_device * device,
223 int subdevice, int *number);
224
225 int (*me_device_query_number_ranges) (struct me_device * device,
226 int subdevice,
227 int unit, int *count);
228
229 int (*me_device_query_range_by_min_max) (struct me_device * device,
230 int subdevice,
231 int unit,
232 int *min,
233 int *max,
234 int *maxdata, int *range);
235
236 int (*me_device_query_range_info) (struct me_device * device,
237 int subdevice,
238 int range,
239 int *unit,
240 int *min, int *max, int *maxdata);
241
242 int (*me_device_query_subdevice_by_type) (struct me_device * device,
243 int start_subdevice,
244 int type,
245 int subtype, int *subdevice);
246
247 int (*me_device_query_subdevice_type) (struct me_device * device,
248 int subdevice,
249 int *type, int *subtype);
250
251 int (*me_device_query_subdevice_caps) (struct me_device * device,
252 int subdevice, int *caps);
253
254 int (*me_device_query_subdevice_caps_args) (struct me_device * device,
255 int subdevice,
256 int cap,
257 int *args, int count);
258
259 int (*me_device_query_timer) (struct me_device * device,
260 int subdevice,
261 int timer,
262 int *base_frequency,
263 uint64_t * min_ticks,
264 uint64_t * max_ticks);
265
266 int (*me_device_query_version_device_driver) (struct me_device * device,
267 int *version);
268
269 int (*me_device_config_load) (struct me_device * device,
270 struct file * filep,
271 me_cfg_device_entry_t * config);
272
273 void (*me_device_destructor) (struct me_device * device);
274} me_device_t;
275
276/**
277 * @brief Initializes a PCI device base class structure.
278 *
279 * @param pci_device The PCI device context as handed over by kernel.
280 *
281 * @return 0 on success.
282 */
283int me_device_pci_init(me_device_t * me_device, struct pci_dev *pci_device);
284
285/**
286 * @brief Initializes a USB device base class structure.
287 *
288 * @param usb_interface The USB device interface as handed over by kernel.
289 *
290 * @return 0 on success.
291 */
292//int me_device_usb_init(me_device_t *me_device, struct usb_interface *interface);
293
294/**
295 * @brief Deinitializes a device base class structure and frees any previously
296 * requested resources related with this structure. It also frees any subdevice
297 * instance hold by the subdevice list.
298 *
299 * @param me_device The device class to deinitialize.
300 */
301void me_device_deinit(me_device_t * me_device);
302
303#endif
304#endif
diff --git a/drivers/staging/meilhaus/medlist.c b/drivers/staging/meilhaus/medlist.c
new file mode 100644
index 000000000000..ef4e36955dc8
--- /dev/null
+++ b/drivers/staging/meilhaus/medlist.c
@@ -0,0 +1,127 @@
1/**
2 * @file me_dlist.c
3 *
4 * @brief Implements the device list class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#include "meerror.h"
28#include "medefines.h"
29
30#include "medlist.h"
31#include "medebug.h"
32
33int me_dlist_query_number_devices(struct me_dlist *dlist, int *number)
34{
35 PDEBUG_LOCKS("called.\n");
36 *number = dlist->n;
37 return ME_ERRNO_SUCCESS;
38}
39
40unsigned int me_dlist_get_number_devices(struct me_dlist *dlist)
41{
42 PDEBUG_LOCKS("called.\n");
43 return dlist->n;
44}
45
46me_device_t *me_dlist_get_device(struct me_dlist * dlist, unsigned int index)
47{
48
49 struct list_head *pos;
50 me_device_t *device = NULL;
51 unsigned int i = 0;
52
53 PDEBUG_LOCKS("called.\n");
54
55 if (index >= dlist->n) {
56 PERROR("Index out of range.\n");
57 return NULL;
58 }
59
60 list_for_each(pos, &dlist->head) {
61 if (i == index) {
62 device = list_entry(pos, me_device_t, list);
63 break;
64 }
65
66 ++i;
67 }
68
69 return device;
70}
71
72void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t * device)
73{
74 PDEBUG_LOCKS("called.\n");
75
76 list_add_tail(&device->list, &dlist->head);
77 ++dlist->n;
78}
79
80me_device_t *me_dlist_del_device_tail(struct me_dlist *dlist)
81{
82
83 struct list_head *last;
84 me_device_t *device;
85
86 PDEBUG_LOCKS("called.\n");
87
88 if (list_empty(&dlist->head))
89 return NULL;
90
91 last = dlist->head.prev;
92
93 device = list_entry(last, me_device_t, list);
94
95 list_del(last);
96
97 --dlist->n;
98
99 return device;
100}
101
102int me_dlist_init(me_dlist_t * dlist)
103{
104 PDEBUG_LOCKS("called.\n");
105
106 INIT_LIST_HEAD(&dlist->head);
107 dlist->n = 0;
108 return 0;
109}
110
111void me_dlist_deinit(me_dlist_t * dlist)
112{
113
114 struct list_head *s;
115 me_device_t *device;
116
117 PDEBUG_LOCKS("called.\n");
118
119 while (!list_empty(&dlist->head)) {
120 s = dlist->head.next;
121 list_del(s);
122 device = list_entry(s, me_device_t, list);
123 device->me_device_destructor(device);
124 }
125
126 dlist->n = 0;
127}
diff --git a/drivers/staging/meilhaus/medlist.h b/drivers/staging/meilhaus/medlist.h
new file mode 100644
index 000000000000..091c11e48ed2
--- /dev/null
+++ b/drivers/staging/meilhaus/medlist.h
@@ -0,0 +1,91 @@
1/**
2 * @file me_dlist.h
3 *
4 * @brief Provides the device list class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _ME_DLIST_H_
10#define _ME_DLIST_H_
11
12#include <linux/list.h>
13
14#include "medevice.h"
15
16#ifdef __KERNEL__
17
18/**
19 * @brief The device list container.
20 */
21typedef struct me_dlist {
22 struct list_head head; /**< The head of the internal list. */
23 unsigned int n; /**< The number of devices in the list. */
24} me_dlist_t;
25
26/**
27 * @brief Queries the number of devices currently inside the list.
28 *
29 * @param dlist The device list to query.
30 * @param[out] number The number of devices.
31 *
32 * @return ME-iDS error code.
33 */
34int me_dlist_query_number_devices(struct me_dlist *dlist, int *number);
35
36/**
37 * @brief Returns the number of devices currently inside the list.
38 *
39 * @param dlist The device list to query.
40 *
41 * @return The number of devices in the list.
42 */
43unsigned int me_dlist_get_number_devices(struct me_dlist *dlist);
44
45/**
46 * @brief Get a device by index.
47 *
48 * @param dlist The device list to query.
49 * @param index The index of the device to get in the list.
50 *
51 * @return The device at index if available.\n
52 * NULL if the index is out of range.
53 */
54me_device_t *me_dlist_get_device(struct me_dlist *dlist, unsigned int index);
55
56/**
57 * @brief Adds a device to the tail of the list.
58 *
59 * @param dlist The device list to add a device to.
60 * @param device The device to add to the list.
61 */
62void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t * device);
63
64/**
65 * @brief Removes a device from the tail of the list.
66 *
67 * @param dlist The device list.
68 *
69 * @return Pointer to the removed subdeivce.\n
70 * NULL in cases where the list was empty.
71 */
72me_device_t *me_dlist_del_device_tail(struct me_dlist *dlist);
73
74/**
75 * @brief Initializes a device list structure.
76 *
77 * @param lock The device list structure to initialize.
78 * @return 0 on success.
79 */
80int me_dlist_init(me_dlist_t * dlist);
81
82/**
83 * @brief Deinitializes a device list structure and destructs every device in it.
84 *
85 * @param dlist The device list structure to deinitialize.
86 * @return 0 on success.
87 */
88void me_dlist_deinit(me_dlist_t * dlist);
89
90#endif
91#endif
diff --git a/drivers/staging/meilhaus/medlock.c b/drivers/staging/meilhaus/medlock.c
new file mode 100644
index 000000000000..f649e3da4f05
--- /dev/null
+++ b/drivers/staging/meilhaus/medlock.c
@@ -0,0 +1,195 @@
1/**
2 * @file medlock.c
3 *
4 * @brief Implements the device lock class.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#include <linux/spinlock.h>
28
29#include "medefines.h"
30#include "meerror.h"
31
32#include "medebug.h"
33#include "meslist.h"
34#include "mesubdevice.h"
35#include "medlock.h"
36
37int me_dlock_enter(struct me_dlock *dlock, struct file *filep)
38{
39 PDEBUG_LOCKS("executed.\n");
40
41 spin_lock(&dlock->spin_lock);
42
43 if ((dlock->filep) != NULL && (dlock->filep != filep)) {
44 PERROR("Device is locked by another process.\n");
45 spin_unlock(&dlock->spin_lock);
46 return ME_ERRNO_LOCKED;
47 }
48
49 dlock->count++;
50
51 spin_unlock(&dlock->spin_lock);
52
53 return ME_ERRNO_SUCCESS;
54}
55
56int me_dlock_exit(struct me_dlock *dlock, struct file *filep)
57{
58 PDEBUG_LOCKS("executed.\n");
59
60 spin_lock(&dlock->spin_lock);
61 dlock->count--;
62 spin_unlock(&dlock->spin_lock);
63
64 return ME_ERRNO_SUCCESS;
65}
66
67int me_dlock_lock(struct me_dlock *dlock,
68 struct file *filep, int lock, int flags, me_slist_t * slist)
69{
70 int err = ME_ERRNO_SUCCESS;
71 int i;
72 me_subdevice_t *subdevice;
73
74 PDEBUG_LOCKS("executed.\n");
75
76 spin_lock(&dlock->spin_lock);
77
78 switch (lock) {
79
80 case ME_LOCK_RELEASE:
81 if ((dlock->filep == filep) || (dlock->filep == NULL)) {
82 dlock->filep = NULL;
83
84 /* Unlock all possibly locked subdevices. */
85
86 for (i = 0; i < me_slist_get_number_subdevices(slist);
87 i++) {
88 subdevice = me_slist_get_subdevice(slist, i);
89
90 if (subdevice)
91 err =
92 subdevice->
93 me_subdevice_lock_subdevice
94 (subdevice, filep, ME_LOCK_RELEASE,
95 flags);
96 else
97 err = ME_ERRNO_INTERNAL;
98 }
99 }
100
101 break;
102
103 case ME_LOCK_SET:
104 if (dlock->count) {
105 PERROR("Device is used by another process.\n");
106 err = ME_ERRNO_USED;
107 } else if ((dlock->filep != NULL) && (dlock->filep != filep)) {
108 PERROR("Device is locked by another process.\n");
109 err = ME_ERRNO_LOCKED;
110 } else if (dlock->filep == NULL) {
111 /* Check any subdevice is locked by another process. */
112
113 for (i = 0; i < me_slist_get_number_subdevices(slist);
114 i++) {
115 subdevice = me_slist_get_subdevice(slist, i);
116
117 if (subdevice) {
118 if ((err =
119 subdevice->
120 me_subdevice_lock_subdevice
121 (subdevice, filep, ME_LOCK_CHECK,
122 flags))) {
123 PERROR
124 ("A subdevice is locked by another process.\n");
125 break;
126 }
127 } else {
128 err = ME_ERRNO_INTERNAL;
129 }
130 }
131
132 /* If no subdevices are locked by other processes,
133 we can take ownership of the device. Otherwise we jump ahead. */
134 if (!err)
135 dlock->filep = filep;
136 }
137
138 break;
139
140 case ME_LOCK_CHECK:
141 if (dlock->count) {
142 err = ME_ERRNO_USED;
143 } else if ((dlock->filep != NULL) && (dlock->filep != filep)) {
144 err = ME_ERRNO_LOCKED;
145 } else if (dlock->filep == NULL) {
146 for (i = 0; i < me_slist_get_number_subdevices(slist);
147 i++) {
148 subdevice = me_slist_get_subdevice(slist, i);
149
150 if (subdevice) {
151 if ((err =
152 subdevice->
153 me_subdevice_lock_subdevice
154 (subdevice, filep, ME_LOCK_CHECK,
155 flags))) {
156 PERROR
157 ("A subdevice is locked by another process.\n");
158 break;
159 }
160 } else {
161 err = ME_ERRNO_INTERNAL;
162 }
163 }
164 }
165
166 break;
167
168 default:
169 PERROR("Invalid lock.\n");
170
171 err = ME_ERRNO_INVALID_LOCK;
172
173 break;
174 }
175
176 spin_unlock(&dlock->spin_lock);
177
178 return err;
179}
180
181void me_dlock_deinit(struct me_dlock *dlock)
182{
183 PDEBUG_LOCKS("executed.\n");
184}
185
186int me_dlock_init(me_dlock_t * dlock)
187{
188 PDEBUG_LOCKS("executed.\n");
189
190 dlock->filep = NULL;
191 dlock->count = 0;
192 spin_lock_init(&dlock->spin_lock);
193
194 return 0;
195}
diff --git a/drivers/staging/meilhaus/medlock.h b/drivers/staging/meilhaus/medlock.h
new file mode 100644
index 000000000000..4d6ddc8e58a1
--- /dev/null
+++ b/drivers/staging/meilhaus/medlock.h
@@ -0,0 +1,76 @@
1/**
2 * @file medlock.h
3 *
4 * @brief Provides the device lock class.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _MEDLOCK_H_
10#define _MEDLOCK_H_
11
12#include <linux/spinlock.h>
13
14#ifdef __KERNEL__
15
16/**
17 * @brief The device lock class.
18 */
19typedef struct me_dlock {
20 struct file *filep; /**< Pointer to file structure holding the device. */
21 int count; /**< Number of tasks which are inside the device. */
22 spinlock_t spin_lock; /**< Spin lock protecting the attributes from concurrent access. */
23} me_dlock_t;
24
25/**
26 * @brief Tries to enter a device.
27 *
28 * @param dlock The device lock instance.
29 * @param filep The file structure identifying the calling process.
30 *
31 * @return 0 on success.
32 */
33int me_dlock_enter(struct me_dlock *dlock, struct file *filep);
34
35/**
36 * @brief Exits a device.
37 *
38 * @param dlock The device lock instance.
39 * @param filep The file structure identifying the calling process.
40 *
41 * @return 0 on success.
42 */
43int me_dlock_exit(struct me_dlock *dlock, struct file *filep);
44
45/**
46 * @brief Tries to perform a locking action on a device.
47 *
48 * @param dlock The device lock instance.
49 * @param filep The file structure identifying the calling process.
50 * @param The action to be done.
51 * @param flags Flags from user space.
52 * @param slist The subdevice list of the device.
53 *
54 * @return 0 on success.
55 */
56int me_dlock_lock(struct me_dlock *dlock,
57 struct file *filep, int lock, int flags, me_slist_t * slist);
58
59/**
60 * @brief Initializes a lock structure.
61 *
62 * @param dlock The lock structure to initialize.
63 * @return 0 on success.
64 */
65int me_dlock_init(me_dlock_t * dlock);
66
67/**
68 * @brief Deinitializes a lock structure.
69 *
70 * @param dlock The lock structure to deinitialize.
71 * @return 0 on success.
72 */
73void me_dlock_deinit(me_dlock_t * dlock);
74
75#endif
76#endif
diff --git a/drivers/staging/meilhaus/medriver.h b/drivers/staging/meilhaus/medriver.h
new file mode 100644
index 000000000000..02e2408ce5f3
--- /dev/null
+++ b/drivers/staging/meilhaus/medriver.h
@@ -0,0 +1,350 @@
1/*
2 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File : medriver.h
5 * Author : GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
6 * Author: Krzysztof Gantzke <k.gantzke@meilhaus.de>
7 */
8
9#ifndef _MEDRIVER_H_
10#define _MEDRIVER_H_
11
12#include "metypes.h"
13#include "meerror.h"
14#include "medefines.h"
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20 /*===========================================================================
21 Functions to access the driver system
22 =========================================================================*/
23
24 int meOpen(int iFlags);
25 int meClose(int iFlags);
26
27 int meLockDriver(int iLock, int iFlags);
28 int meLockDevice(int iDevice, int iLock, int iFlags);
29 int meLockSubdevice(int iDevice, int iSubdevice, int iLock, int iFlags);
30
31 /*===========================================================================
32 Error handling functions
33 =========================================================================*/
34
35 int meErrorGetLastMessage(char *pcErrorMsg, int iCount);
36 int meErrorGetMessage(int iErrorCode, char *pcErrorMsg, int iCount);
37 int meErrorSetDefaultProc(int iSwitch);
38 int meErrorSetUserProc(meErrorCB_t pErrorProc);
39
40
41 /*===========================================================================
42 Functions to perform I/O on a device
43 =========================================================================*/
44
45 int meIOIrqSetCallback(
46 int iDevice,
47 int iSubdevice,
48 meIOIrqCB_t pCallback,
49 void *pCallbackContext,
50 int iFlags);
51 int meIOIrqStart(
52 int iDevice,
53 int iSubdevice,
54 int iChannel,
55 int iIrqSource,
56 int iIrqEdge,
57 int iIrqArg,
58 int iFlags);
59 int meIOIrqStop(
60 int iDevice,
61 int iSubdevice,
62 int iChannel,
63 int iFlags);
64 int meIOIrqWait(
65 int iDevice,
66 int iSubdevice,
67 int iChannel,
68 int *piIrqCount,
69 int *piValue,
70 int iTimeOut,
71 int iFlags);
72
73 int meIOResetDevice(int iDevice, int iFlags);
74 int meIOResetSubdevice(int iDevice, int iSubdevice, int iFlags);
75
76 int meIOStreamFrequencyToTicks(
77 int iDevice,
78 int iSubdevice,
79 int iTimer,
80 double *pdFrequency,
81 int *piTicksLow,
82 int *piTicksHigh,
83 int iFlags);
84
85 int meIOSingleConfig(
86 int iDevice,
87 int iSubdevice,
88 int iChannel,
89 int iSingleConfig,
90 int iRef,
91 int iTrigChan,
92 int iTrigType,
93 int iTrigEdge,
94 int iFlags);
95 int meIOSingle(meIOSingle_t *pSingleList, int iCount, int iFlags);
96
97 int meIOStreamConfig(
98 int iDevice,
99 int iSubdevice,
100 meIOStreamConfig_t *pConfigList,
101 int iCount,
102 meIOStreamTrigger_t *pTrigger,
103 int iFifoIrqThreshold,
104 int iFlags);
105 int meIOStreamNewValues(
106 int iDevice,
107 int iSubdevice,
108 int iTimeOut,
109 int *piCount,
110 int iFlags);
111 int meIOStreamRead(
112 int iDevice,
113 int iSubdevice,
114 int iReadMode,
115 int *piValues,
116 int *piCount,
117 int iFlags);
118 int meIOStreamWrite(
119 int iDevice,
120 int iSubdevice,
121 int iWriteMode,
122 int *piValues,
123 int *piCount,
124 int iFlags);
125 int meIOStreamStart(meIOStreamStart_t *pStartList, int iCount, int iFlags);
126 int meIOStreamStop(meIOStreamStop_t *pStopList, int iCount, int iFlags);
127 int meIOStreamStatus(
128 int iDevice,
129 int iSubdevice,
130 int iWait,
131 int *piStatus,
132 int *piCount,
133 int iFlags);
134 int meIOStreamSetCallbacks(
135 int iDevice,
136 int iSubdevice,
137 meIOStreamCB_t pStartCB,
138 void *pStartCBContext,
139 meIOStreamCB_t pNewValuesCB,
140 void *pNewValuesCBContext,
141 meIOStreamCB_t pEndCB,
142 void *pEndCBContext,
143 int iFlags);
144 int meIOStreamTimeToTicks(
145 int iDevice,
146 int iSubdevice,
147 int iTimer,
148 double *pdTime,
149 int *piTicksLow,
150 int *piTicksHigh,
151 int iFlags);
152
153
154 /*===========================================================================
155 Functions to query the driver system
156 =========================================================================*/
157
158 int meQueryDescriptionDevice(int iDevice, char *pcDescription, int iCount);
159
160 int meQueryInfoDevice(
161 int iDevice,
162 int *piVendorId,
163 int *piDeviceId,
164 int *piSerialNo,
165 int *piBusType,
166 int *piBusNo,
167 int *piDevNo,
168 int *piFuncNo,
169 int *piPlugged);
170
171 int meQueryNameDevice(int iDevice, char *pcName, int iCount);
172 int meQueryNameDeviceDriver(int iDevice, char *pcName, int iCount);
173
174 int meQueryNumberDevices(int *piNumber);
175 int meQueryNumberSubdevices(int iDevice, int *piNumber);
176 int meQueryNumberChannels(int iDevice, int iSubdevice, int *piNumber);
177 int meQueryNumberRanges(
178 int iDevice,
179 int iSubdevice,
180 int iUnit,
181 int *piNumber);
182
183 int meQueryRangeByMinMax(
184 int iDevice,
185 int iSubdevice,
186 int iUnit,
187 double *pdMin,
188 double *pdMax,
189 int *piMaxData,
190 int *piRange);
191 int meQueryRangeInfo(
192 int iDevice,
193 int iSubdevice,
194 int iRange,
195 int *piUnit,
196 double *pdMin,
197 double *pdMax,
198 int *piMaxData);
199
200 int meQuerySubdeviceByType(
201 int iDevice,
202 int iStartSubdevice,
203 int iType,
204 int iSubtype,
205 int *piSubdevice);
206 int meQuerySubdeviceType(
207 int iDevice,
208 int iSubdevice,
209 int *piType,
210 int *piSubtype);
211 int meQuerySubdeviceCaps(
212 int iDevice,
213 int iSubdevice,
214 int *piCaps);
215 int meQuerySubdeviceCapsArgs(
216 int iDevice,
217 int iSubdevice,
218 int iCap,
219 int *piArgs,
220 int iCount);
221
222 int meQueryVersionLibrary(int *piVersion);
223 int meQueryVersionMainDriver(int *piVersion);
224 int meQueryVersionDeviceDriver(int iDevice, int *piVersion);
225
226
227 /*===========================================================================
228 Common utility functions
229 =========================================================================*/
230
231 int meUtilityExtractValues(
232 int iChannel,
233 int *piAIBuffer,
234 int iAIBufferCount,
235 meIOStreamConfig_t *pConfigList,
236 int iConfigListCount,
237 int *piChanBuffer,
238 int *piChanBufferCount);
239 int meUtilityDigitalToPhysical(
240 double dMin,
241 double dMax,
242 int iMaxData,
243 int iData,
244 int iModuleType,
245 double dRefValue,
246 double *pdPhysical);
247 int meUtilityDigitalToPhysicalV(
248 double dMin,
249 double dMax,
250 int iMaxData,
251 int *piDataBuffer,
252 int iCount,
253 int iModuleType,
254 double dRefValue,
255 double *pdPhysicalBuffer);
256 int meUtilityPhysicalToDigital(
257 double dMin,
258 double dMax,
259 int iMaxData,
260 double dPhysical,
261 int *piData);
262 int meUtilityPWMStart(
263 int iDevice,
264 int iSubdevice1,
265 int iSubdevice2,
266 int iSubdevice3,
267 int iRef,
268 int iPrescaler,
269 int iDutyCycle,
270 int iFlag);
271 int meUtilityPWMStop(int iDevice,
272 int iSubdevice1);
273 int meUtilityPWMRestart(
274 int iDevice,
275 int iSubdevice1,
276 int iRef,
277 int iPrescaler);
278
279
280 /*===========================================================================
281 Load configuration from file into driver system
282 =========================================================================*/
283
284 int meConfigLoad(char *pcConfigFile);
285
286
287 /*===========================================================================
288 Functions to query a remote driver system
289 =========================================================================*/
290
291 int meRQueryDescriptionDevice(
292 char *location,
293 int iDevice,
294 char *pcDescription,
295 int iCount);
296
297 int meRQueryInfoDevice(
298 char *location,
299 int iDevice,
300 int *piVendorId,
301 int *piDeviceId,
302 int *piSerialNo,
303 int *piBusType,
304 int *piBusNo,
305 int *piDevNo,
306 int *piFuncNo,
307 int *piPlugged);
308
309 int meRQueryNameDevice(
310 char *location,
311 int iDevice,
312 char *pcName,
313 int iCount);
314
315 int meRQueryNumberDevices(char *location, int *piNumber);
316 int meRQueryNumberSubdevices(char *location, int iDevice, int *piNumber);
317 int meRQueryNumberChannels(
318 char *location,
319 int iDevice,
320 int iSubdevice,
321 int *piNumber);
322 int meRQueryNumberRanges(
323 char *location,
324 int iDevice,
325 int iSubdevice,
326 int iUnit,
327 int *piNumber);
328
329 int meRQueryRangeInfo(
330 char *location,
331 int iDevice,
332 int iSubdevice,
333 int iRange,
334 int *piUnit,
335 double *pdMin,
336 double *pdMax,
337 int *piMaxData);
338
339 int meRQuerySubdeviceType(
340 char *location,
341 int iDevice,
342 int iSubdevice,
343 int *piType,
344 int *piSubtype);
345
346#ifdef __cplusplus
347}
348#endif
349
350#endif
diff --git a/drivers/staging/meilhaus/medummy.c b/drivers/staging/meilhaus/medummy.c
new file mode 100644
index 000000000000..6a9f08d50bb1
--- /dev/null
+++ b/drivers/staging/meilhaus/medummy.c
@@ -0,0 +1,1266 @@
1/* Device driver for Meilhaus ME-DUMMY devices.
2 * ===========================================
3 *
4 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
5 *
6 * This file is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21/*
22 * User application could also include the kernel header files. But the
23 * real kernel functions are protected by #ifdef __KERNEL__.
24 */
25#ifndef __KERNEL__
26# define __KERNEL__
27#endif
28
29/*
30 * This must be defined before module.h is included. Not needed, when
31 * it is a built in driver.
32 */
33#ifndef MODULE
34# define MODULE
35#endif
36
37#include <linux/module.h>
38#include <linux/slab.h>
39
40#include "meerror.h"
41#include "meinternal.h"
42
43#include "meids.h"
44#include "mecommon.h"
45#include "medevice.h"
46#include "medebug.h"
47
48#include "medummy.h"
49
50static int medummy_io_irq_start(me_device_t * device,
51 struct file *filep,
52 int subdevice,
53 int channel,
54 int irq_source,
55 int irq_edge, int irq_arg, int flags)
56{
57 PDEBUG("executed.\n");
58 return ME_ERRNO_DEVICE_UNPLUGGED;
59}
60
61static int medummy_io_irq_wait(me_device_t * device,
62 struct file *filep,
63 int subdevice,
64 int channel,
65 int *irq_count,
66 int *value, int timeout, int flags)
67{
68 PDEBUG("executed.\n");
69 return ME_ERRNO_DEVICE_UNPLUGGED;
70}
71
72static int medummy_io_irq_stop(me_device_t * device,
73 struct file *filep,
74 int subdevice, int channel, int flags)
75{
76 PDEBUG("executed.\n");
77 return ME_ERRNO_DEVICE_UNPLUGGED;
78}
79
80static int medummy_io_reset_device(me_device_t * device,
81 struct file *filep, int flags)
82{
83 PDEBUG("executed.\n");
84 return ME_ERRNO_DEVICE_UNPLUGGED;
85}
86
87static int medummy_io_reset_subdevice(me_device_t * device,
88 struct file *filep,
89 int subdevice, int flags)
90{
91 PDEBUG("executed.\n");
92 return ME_ERRNO_DEVICE_UNPLUGGED;
93}
94
95static int medummy_io_single_config(me_device_t * device,
96 struct file *filep,
97 int subdevice,
98 int channel,
99 int single_config,
100 int ref,
101 int trig_chan,
102 int trig_type, int trig_edge, int flags)
103{
104 PDEBUG("executed.\n");
105 return ME_ERRNO_DEVICE_UNPLUGGED;
106}
107
108static int medummy_io_single_read(me_device_t * device,
109 struct file *filep,
110 int subdevice,
111 int channel,
112 int *value, int time_out, int flags)
113{
114 PDEBUG("executed.\n");
115 return ME_ERRNO_DEVICE_UNPLUGGED;
116}
117
118static int medummy_io_single_write(me_device_t * device,
119 struct file *filep,
120 int subdevice,
121 int channel,
122 int value, int time_out, int flags)
123{
124 PDEBUG("executed.\n");
125 return ME_ERRNO_DEVICE_UNPLUGGED;
126}
127
128static int medummy_io_stream_config(me_device_t * device,
129 struct file *filep,
130 int subdevice,
131 meIOStreamConfig_t * config_list,
132 int count,
133 meIOStreamTrigger_t * trigger,
134 int fifo_irq_threshold, int flags)
135{
136 PDEBUG("executed.\n");
137 return ME_ERRNO_DEVICE_UNPLUGGED;
138}
139
140static int medummy_io_stream_new_values(me_device_t * device,
141 struct file *filep,
142 int subdevice,
143 int timeout, int *count, int flags)
144{
145 PDEBUG("executed.\n");
146 return ME_ERRNO_DEVICE_UNPLUGGED;
147}
148
149static int medummy_io_stream_read(me_device_t * device,
150 struct file *filep,
151 int subdevice,
152 int read_mode,
153 int *values, int *count, int flags)
154{
155 PDEBUG("executed.\n");
156 return ME_ERRNO_DEVICE_UNPLUGGED;
157}
158
159static int medummy_io_stream_start(me_device_t * device,
160 struct file *filep,
161 int subdevice,
162 int start_mode, int time_out, int flags)
163{
164 PDEBUG("executed.\n");
165 return ME_ERRNO_DEVICE_UNPLUGGED;
166}
167
168static int medummy_io_stream_status(me_device_t * device,
169 struct file *filep,
170 int subdevice,
171 int wait,
172 int *status, int *values, int flags)
173{
174 PDEBUG("executed.\n");
175 return ME_ERRNO_DEVICE_UNPLUGGED;
176}
177
178static int medummy_io_stream_stop(me_device_t * device,
179 struct file *filep,
180 int subdevice, int stop_mode, int flags)
181{
182 PDEBUG("executed.\n");
183 return ME_ERRNO_DEVICE_UNPLUGGED;
184}
185
186static int medummy_io_stream_write(me_device_t * device,
187 struct file *filep,
188 int subdevice,
189 int write_mode,
190 int *values, int *count, int flags)
191{
192 PDEBUG("executed.\n");
193 return ME_ERRNO_DEVICE_UNPLUGGED;
194}
195
196static int medummy_lock_device(me_device_t * device,
197 struct file *filep, int lock, int flags)
198{
199 PDEBUG("executed.\n");
200 return ME_ERRNO_DEVICE_UNPLUGGED;
201}
202
203static int medummy_lock_subdevice(me_device_t * device,
204 struct file *filep,
205 int subdevice, int lock, int flags)
206{
207 PDEBUG("executed.\n");
208 return ME_ERRNO_DEVICE_UNPLUGGED;
209}
210
211static int medummy_query_description_device(me_device_t * device,
212 char **description)
213{
214 medummy_device_t *instance = (medummy_device_t *) device;
215
216 PDEBUG("executed.\n");
217
218// if (instance->magic != MEDUMMY_MAGIC_NUMBER)
219// {
220// PERROR("Wrong magic number.\n");
221// return ME_ERRNO_INTERNAL;
222// }
223
224 switch (instance->device_id) {
225
226 case PCI_DEVICE_ID_MEILHAUS_ME1000:
227
228 case PCI_DEVICE_ID_MEILHAUS_ME1000_A:
229
230 case PCI_DEVICE_ID_MEILHAUS_ME1000_B:
231 *description = ME1000_DESCRIPTION_DEVICE_ME1000;
232
233 break;
234
235 case PCI_DEVICE_ID_MEILHAUS_ME1400:
236 *description = ME1400_DESCRIPTION_DEVICE_ME1400;
237
238 break;
239
240 case PCI_DEVICE_ID_MEILHAUS_ME140A:
241 *description = ME1400_DESCRIPTION_DEVICE_ME1400A;
242
243 break;
244
245 case PCI_DEVICE_ID_MEILHAUS_ME140B:
246 *description = ME1400_DESCRIPTION_DEVICE_ME1400B;
247
248 break;
249
250 case PCI_DEVICE_ID_MEILHAUS_ME14E0:
251 *description = ME1400_DESCRIPTION_DEVICE_ME1400E;
252
253 break;
254
255 case PCI_DEVICE_ID_MEILHAUS_ME14EA:
256 *description = ME1400_DESCRIPTION_DEVICE_ME1400EA;
257
258 break;
259
260 case PCI_DEVICE_ID_MEILHAUS_ME14EB:
261 *description = ME1400_DESCRIPTION_DEVICE_ME1400EB;
262
263 break;
264
265 case PCI_DEVICE_ID_MEILHAUS_ME140C:
266 *description = ME1400_DESCRIPTION_DEVICE_ME1400C;
267
268 break;
269
270 case PCI_DEVICE_ID_MEILHAUS_ME140D:
271 *description = ME1400_DESCRIPTION_DEVICE_ME1400D;
272
273 break;
274
275 case PCI_DEVICE_ID_MEILHAUS_ME1600_4U:
276 *description = ME1600_DESCRIPTION_DEVICE_ME16004U;
277
278 break;
279
280 case PCI_DEVICE_ID_MEILHAUS_ME1600_8U:
281 *description = ME1600_DESCRIPTION_DEVICE_ME16008U;
282
283 break;
284
285 case PCI_DEVICE_ID_MEILHAUS_ME1600_12U:
286 *description = ME1600_DESCRIPTION_DEVICE_ME160012U;
287
288 break;
289
290 case PCI_DEVICE_ID_MEILHAUS_ME1600_16U:
291 *description = ME1600_DESCRIPTION_DEVICE_ME160016U;
292
293 break;
294
295 case PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I:
296 *description = ME1600_DESCRIPTION_DEVICE_ME160016U8I;
297
298 break;
299
300 case PCI_DEVICE_ID_MEILHAUS_ME4610:
301 *description = ME4600_DESCRIPTION_DEVICE_ME4610;
302
303 break;
304
305 case PCI_DEVICE_ID_MEILHAUS_ME4650:
306 *description = ME4600_DESCRIPTION_DEVICE_ME4650;
307
308 break;
309
310 case PCI_DEVICE_ID_MEILHAUS_ME4660:
311 *description = ME4600_DESCRIPTION_DEVICE_ME4660;
312
313 break;
314
315 case PCI_DEVICE_ID_MEILHAUS_ME4660I:
316 *description = ME4600_DESCRIPTION_DEVICE_ME4660I;
317
318 break;
319
320 case PCI_DEVICE_ID_MEILHAUS_ME4660S:
321 *description = ME4600_DESCRIPTION_DEVICE_ME4660S;
322
323 break;
324
325 case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
326 *description = ME4600_DESCRIPTION_DEVICE_ME4660IS;
327
328 break;
329
330 case PCI_DEVICE_ID_MEILHAUS_ME4670:
331 *description = ME4600_DESCRIPTION_DEVICE_ME4670;
332
333 break;
334
335 case PCI_DEVICE_ID_MEILHAUS_ME4670I:
336 *description = ME4600_DESCRIPTION_DEVICE_ME4670I;
337
338 break;
339
340 case PCI_DEVICE_ID_MEILHAUS_ME4670S:
341 *description = ME4600_DESCRIPTION_DEVICE_ME4670S;
342
343 break;
344
345 case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
346 *description = ME4600_DESCRIPTION_DEVICE_ME4670IS;
347
348 break;
349
350 case PCI_DEVICE_ID_MEILHAUS_ME4680:
351 *description = ME4600_DESCRIPTION_DEVICE_ME4680;
352
353 break;
354
355 case PCI_DEVICE_ID_MEILHAUS_ME4680I:
356 *description = ME4600_DESCRIPTION_DEVICE_ME4680I;
357
358 break;
359
360 case PCI_DEVICE_ID_MEILHAUS_ME4680S:
361 *description = ME4600_DESCRIPTION_DEVICE_ME4680S;
362
363 break;
364
365 case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
366 *description = ME4600_DESCRIPTION_DEVICE_ME4680IS;
367
368 break;
369
370 case PCI_DEVICE_ID_MEILHAUS_ME6004:
371 *description = ME6000_DESCRIPTION_DEVICE_ME60004;
372
373 break;
374
375 case PCI_DEVICE_ID_MEILHAUS_ME6008:
376 *description = ME6000_DESCRIPTION_DEVICE_ME60008;
377
378 break;
379
380 case PCI_DEVICE_ID_MEILHAUS_ME600F:
381 *description = ME6000_DESCRIPTION_DEVICE_ME600016;
382
383 break;
384
385 case PCI_DEVICE_ID_MEILHAUS_ME6014:
386 *description = ME6000_DESCRIPTION_DEVICE_ME6000I4;
387
388 break;
389
390 case PCI_DEVICE_ID_MEILHAUS_ME6018:
391 *description = ME6000_DESCRIPTION_DEVICE_ME6000I8;
392
393 break;
394
395 case PCI_DEVICE_ID_MEILHAUS_ME601F:
396 *description = ME6000_DESCRIPTION_DEVICE_ME6000I16;
397
398 break;
399
400 case PCI_DEVICE_ID_MEILHAUS_ME6034:
401 *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4;
402
403 break;
404
405 case PCI_DEVICE_ID_MEILHAUS_ME6038:
406 *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8;
407
408 break;
409
410 case PCI_DEVICE_ID_MEILHAUS_ME603F:
411 *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16;
412
413 break;
414
415 case PCI_DEVICE_ID_MEILHAUS_ME6104:
416 *description = ME6000_DESCRIPTION_DEVICE_ME61004;
417
418 break;
419
420 case PCI_DEVICE_ID_MEILHAUS_ME6108:
421 *description = ME6000_DESCRIPTION_DEVICE_ME61008;
422
423 break;
424
425 case PCI_DEVICE_ID_MEILHAUS_ME610F:
426 *description = ME6000_DESCRIPTION_DEVICE_ME610016;
427
428 break;
429
430 case PCI_DEVICE_ID_MEILHAUS_ME6114:
431 *description = ME6000_DESCRIPTION_DEVICE_ME6100I4;
432
433 break;
434
435 case PCI_DEVICE_ID_MEILHAUS_ME6118:
436 *description = ME6000_DESCRIPTION_DEVICE_ME6100I8;
437
438 break;
439
440 case PCI_DEVICE_ID_MEILHAUS_ME611F:
441 *description = ME6000_DESCRIPTION_DEVICE_ME6100I16;
442
443 break;
444
445 case PCI_DEVICE_ID_MEILHAUS_ME6134:
446 *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4;
447
448 break;
449
450 case PCI_DEVICE_ID_MEILHAUS_ME6138:
451 *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8;
452
453 break;
454
455 case PCI_DEVICE_ID_MEILHAUS_ME613F:
456 *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16;
457
458 break;
459
460 case PCI_DEVICE_ID_MEILHAUS_ME6044:
461 *description = ME6000_DESCRIPTION_DEVICE_ME60004DIO;
462
463 break;
464
465 case PCI_DEVICE_ID_MEILHAUS_ME6048:
466 *description = ME6000_DESCRIPTION_DEVICE_ME60008DIO;
467
468 break;
469
470 case PCI_DEVICE_ID_MEILHAUS_ME604F:
471 *description = ME6000_DESCRIPTION_DEVICE_ME600016DIO;
472
473 break;
474
475 case PCI_DEVICE_ID_MEILHAUS_ME6054:
476 *description = ME6000_DESCRIPTION_DEVICE_ME6000I4DIO;
477
478 break;
479
480 case PCI_DEVICE_ID_MEILHAUS_ME6058:
481 *description = ME6000_DESCRIPTION_DEVICE_ME6000I8DIO;
482
483 break;
484
485 case PCI_DEVICE_ID_MEILHAUS_ME605F:
486 *description = ME6000_DESCRIPTION_DEVICE_ME6000I16DIO;
487
488 break;
489
490 case PCI_DEVICE_ID_MEILHAUS_ME6074:
491 *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4DIO;
492
493 break;
494
495 case PCI_DEVICE_ID_MEILHAUS_ME6078:
496 *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8DIO;
497
498 break;
499
500 case PCI_DEVICE_ID_MEILHAUS_ME607F:
501 *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16DIO;
502
503 break;
504
505 case PCI_DEVICE_ID_MEILHAUS_ME6144:
506 *description = ME6000_DESCRIPTION_DEVICE_ME61004DIO;
507
508 break;
509
510 case PCI_DEVICE_ID_MEILHAUS_ME6148:
511 *description = ME6000_DESCRIPTION_DEVICE_ME61008DIO;
512
513 break;
514
515 case PCI_DEVICE_ID_MEILHAUS_ME614F:
516 *description = ME6000_DESCRIPTION_DEVICE_ME610016DIO;
517
518 break;
519
520 case PCI_DEVICE_ID_MEILHAUS_ME6154:
521 *description = ME6000_DESCRIPTION_DEVICE_ME6100I4DIO;
522
523 break;
524
525 case PCI_DEVICE_ID_MEILHAUS_ME6158:
526 *description = ME6000_DESCRIPTION_DEVICE_ME6100I8DIO;
527
528 break;
529
530 case PCI_DEVICE_ID_MEILHAUS_ME615F:
531 *description = ME6000_DESCRIPTION_DEVICE_ME6100I16DIO;
532
533 break;
534
535 case PCI_DEVICE_ID_MEILHAUS_ME6174:
536 *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4DIO;
537
538 break;
539
540 case PCI_DEVICE_ID_MEILHAUS_ME6178:
541 *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8DIO;
542
543 break;
544
545 case PCI_DEVICE_ID_MEILHAUS_ME617F:
546 *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16DIO;
547
548 break;
549
550 case PCI_DEVICE_ID_MEILHAUS_ME6259:
551 *description = ME6000_DESCRIPTION_DEVICE_ME6200I9DIO;
552
553 break;
554
555 case PCI_DEVICE_ID_MEILHAUS_ME6359:
556 *description = ME6000_DESCRIPTION_DEVICE_ME6300I9DIO;
557
558 break;
559
560 case PCI_DEVICE_ID_MEILHAUS_ME0630:
561 *description = ME0600_DESCRIPTION_DEVICE_ME0630;
562
563 break;
564
565 case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
566 *description = ME8100_DESCRIPTION_DEVICE_ME8100A;
567
568 break;
569
570 case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
571 *description = ME8100_DESCRIPTION_DEVICE_ME8100B;
572
573 break;
574
575 case PCI_DEVICE_ID_MEILHAUS_ME0940:
576 *description = ME0900_DESCRIPTION_DEVICE_ME0940;
577
578 break;
579
580 case PCI_DEVICE_ID_MEILHAUS_ME0950:
581 *description = ME0900_DESCRIPTION_DEVICE_ME0950;
582
583 break;
584
585 case PCI_DEVICE_ID_MEILHAUS_ME0960:
586 *description = ME0900_DESCRIPTION_DEVICE_ME0960;
587
588 break;
589/*
590 case USB_DEVICE_ID_MEPHISTO_S1:
591 *description = MEPHISTO_S1_DESCRIPTION_DEVICE;
592
593 break;
594*/
595 default:
596 *description = EMPTY_DESCRIPTION_DEVICE;
597 PERROR("Invalid device id in device info.\n");
598
599 return ME_ERRNO_INTERNAL;
600 }
601
602 return ME_ERRNO_DEVICE_UNPLUGGED;
603}
604
605static int medummy_query_info_device(me_device_t * device,
606 int *vendor_id,
607 int *device_id,
608 int *serial_no,
609 int *bus_type,
610 int *bus_no,
611 int *dev_no, int *func_no, int *plugged)
612{
613 medummy_device_t *instance = (medummy_device_t *) device;
614
615 PDEBUG("executed.\n");
616
617// if (instance->magic != MEDUMMY_MAGIC_NUMBER)
618// {
619// PERROR("Wrong magic number.\n");
620// return ME_ERRNO_INTERNAL;
621// }
622
623 *vendor_id = instance->vendor_id;
624 *device_id = instance->device_id;
625 *serial_no = instance->serial_no;
626 *bus_type = instance->bus_type;
627 *bus_no = instance->bus_no;
628 *dev_no = instance->dev_no;
629 *func_no = instance->func_no;
630 *plugged = ME_PLUGGED_OUT;
631
632 return ME_ERRNO_SUCCESS;
633}
634
635static int medummy_query_name_device_driver(me_device_t * device, char **name)
636{
637 PDEBUG("executed.\n");
638 *name = MEDUMMY_NAME_DRIVER;
639 return ME_ERRNO_SUCCESS;
640}
641
642static int medummy_query_name_device(me_device_t * device, char **name)
643{
644 medummy_device_t *instance = (medummy_device_t *) device;
645
646 PDEBUG("executed.\n");
647
648// // // if (instance->magic != MEDUMMY_MAGIC_NUMBER)
649// // // {
650// // // PERROR("Wrong magic number.\n");
651// // // return ME_ERRNO_INTERNAL;
652// // // }
653
654 switch (instance->device_id) {
655
656 case PCI_DEVICE_ID_MEILHAUS_ME1000:
657
658 case PCI_DEVICE_ID_MEILHAUS_ME1000_A:
659
660 case PCI_DEVICE_ID_MEILHAUS_ME1000_B:
661 *name = ME1000_NAME_DEVICE_ME1000;
662
663 break;
664
665 case PCI_DEVICE_ID_MEILHAUS_ME1400:
666 *name = ME1400_NAME_DEVICE_ME1400;
667
668 break;
669
670 case PCI_DEVICE_ID_MEILHAUS_ME140A:
671 *name = ME1400_NAME_DEVICE_ME1400A;
672
673 break;
674
675 case PCI_DEVICE_ID_MEILHAUS_ME140B:
676 *name = ME1400_NAME_DEVICE_ME1400B;
677
678 break;
679
680 case PCI_DEVICE_ID_MEILHAUS_ME14E0:
681 *name = ME1400_NAME_DEVICE_ME1400E;
682
683 break;
684
685 case PCI_DEVICE_ID_MEILHAUS_ME14EA:
686 *name = ME1400_NAME_DEVICE_ME1400EA;
687
688 break;
689
690 case PCI_DEVICE_ID_MEILHAUS_ME14EB:
691 *name = ME1400_NAME_DEVICE_ME1400EB;
692
693 break;
694
695 case PCI_DEVICE_ID_MEILHAUS_ME140C:
696 *name = ME1400_NAME_DEVICE_ME1400C;
697
698 break;
699
700 case PCI_DEVICE_ID_MEILHAUS_ME140D:
701 *name = ME1400_NAME_DEVICE_ME1400D;
702
703 break;
704
705 case PCI_DEVICE_ID_MEILHAUS_ME1600_4U:
706 *name = ME1600_NAME_DEVICE_ME16004U;
707
708 break;
709
710 case PCI_DEVICE_ID_MEILHAUS_ME1600_8U:
711 *name = ME1600_NAME_DEVICE_ME16008U;
712
713 break;
714
715 case PCI_DEVICE_ID_MEILHAUS_ME1600_12U:
716 *name = ME1600_NAME_DEVICE_ME160012U;
717
718 break;
719
720 case PCI_DEVICE_ID_MEILHAUS_ME1600_16U:
721 *name = ME1600_NAME_DEVICE_ME160016U;
722
723 break;
724
725 case PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I:
726 *name = ME1600_NAME_DEVICE_ME160016U8I;
727
728 break;
729
730 case PCI_DEVICE_ID_MEILHAUS_ME4610:
731 *name = ME4600_NAME_DEVICE_ME4610;
732
733 break;
734
735 case PCI_DEVICE_ID_MEILHAUS_ME4650:
736 *name = ME4600_NAME_DEVICE_ME4650;
737
738 break;
739
740 case PCI_DEVICE_ID_MEILHAUS_ME4660:
741 *name = ME4600_NAME_DEVICE_ME4660;
742
743 break;
744
745 case PCI_DEVICE_ID_MEILHAUS_ME4660I:
746 *name = ME4600_NAME_DEVICE_ME4660I;
747
748 break;
749
750 case PCI_DEVICE_ID_MEILHAUS_ME4670:
751 *name = ME4600_NAME_DEVICE_ME4670;
752
753 break;
754
755 case PCI_DEVICE_ID_MEILHAUS_ME4670I:
756 *name = ME4600_NAME_DEVICE_ME4670I;
757
758 break;
759
760 case PCI_DEVICE_ID_MEILHAUS_ME4670S:
761 *name = ME4600_NAME_DEVICE_ME4670S;
762
763 break;
764
765 case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
766 *name = ME4600_NAME_DEVICE_ME4670IS;
767
768 break;
769
770 case PCI_DEVICE_ID_MEILHAUS_ME4680:
771 *name = ME4600_NAME_DEVICE_ME4680;
772
773 break;
774
775 case PCI_DEVICE_ID_MEILHAUS_ME4680I:
776 *name = ME4600_NAME_DEVICE_ME4680I;
777
778 break;
779
780 case PCI_DEVICE_ID_MEILHAUS_ME4680S:
781 *name = ME4600_NAME_DEVICE_ME4680S;
782
783 break;
784
785 case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
786 *name = ME4600_NAME_DEVICE_ME4680IS;
787
788 break;
789
790 case PCI_DEVICE_ID_MEILHAUS_ME6004:
791 *name = ME6000_NAME_DEVICE_ME60004;
792
793 break;
794
795 case PCI_DEVICE_ID_MEILHAUS_ME6008:
796 *name = ME6000_NAME_DEVICE_ME60008;
797
798 break;
799
800 case PCI_DEVICE_ID_MEILHAUS_ME600F:
801 *name = ME6000_NAME_DEVICE_ME600016;
802
803 break;
804
805 case PCI_DEVICE_ID_MEILHAUS_ME6014:
806 *name = ME6000_NAME_DEVICE_ME6000I4;
807
808 break;
809
810 case PCI_DEVICE_ID_MEILHAUS_ME6018:
811 *name = ME6000_NAME_DEVICE_ME6000I8;
812
813 break;
814
815 case PCI_DEVICE_ID_MEILHAUS_ME601F:
816 *name = ME6000_NAME_DEVICE_ME6000I16;
817
818 break;
819
820 case PCI_DEVICE_ID_MEILHAUS_ME6034:
821 *name = ME6000_NAME_DEVICE_ME6000ISLE4;
822
823 break;
824
825 case PCI_DEVICE_ID_MEILHAUS_ME6038:
826 *name = ME6000_NAME_DEVICE_ME6000ISLE8;
827
828 break;
829
830 case PCI_DEVICE_ID_MEILHAUS_ME603F:
831 *name = ME6000_NAME_DEVICE_ME6000ISLE16;
832
833 break;
834
835 case PCI_DEVICE_ID_MEILHAUS_ME6104:
836 *name = ME6000_NAME_DEVICE_ME61004;
837
838 break;
839
840 case PCI_DEVICE_ID_MEILHAUS_ME6108:
841 *name = ME6000_NAME_DEVICE_ME61008;
842
843 break;
844
845 case PCI_DEVICE_ID_MEILHAUS_ME610F:
846 *name = ME6000_NAME_DEVICE_ME610016;
847
848 break;
849
850 case PCI_DEVICE_ID_MEILHAUS_ME6114:
851 *name = ME6000_NAME_DEVICE_ME6100I4;
852
853 break;
854
855 case PCI_DEVICE_ID_MEILHAUS_ME6118:
856 *name = ME6000_NAME_DEVICE_ME6100I8;
857
858 break;
859
860 case PCI_DEVICE_ID_MEILHAUS_ME611F:
861 *name = ME6000_NAME_DEVICE_ME6100I16;
862
863 break;
864
865 case PCI_DEVICE_ID_MEILHAUS_ME6134:
866 *name = ME6000_NAME_DEVICE_ME6100ISLE4;
867
868 break;
869
870 case PCI_DEVICE_ID_MEILHAUS_ME6138:
871 *name = ME6000_NAME_DEVICE_ME6100ISLE8;
872
873 break;
874
875 case PCI_DEVICE_ID_MEILHAUS_ME613F:
876 *name = ME6000_NAME_DEVICE_ME6100ISLE16;
877
878 break;
879
880 case PCI_DEVICE_ID_MEILHAUS_ME6044:
881 *name = ME6000_NAME_DEVICE_ME60004DIO;
882
883 break;
884
885 case PCI_DEVICE_ID_MEILHAUS_ME6048:
886 *name = ME6000_NAME_DEVICE_ME60008DIO;
887
888 break;
889
890 case PCI_DEVICE_ID_MEILHAUS_ME604F:
891 *name = ME6000_NAME_DEVICE_ME600016DIO;
892
893 break;
894
895 case PCI_DEVICE_ID_MEILHAUS_ME6054:
896 *name = ME6000_NAME_DEVICE_ME6000I4DIO;
897
898 break;
899
900 case PCI_DEVICE_ID_MEILHAUS_ME6058:
901 *name = ME6000_NAME_DEVICE_ME6000I8DIO;
902
903 break;
904
905 case PCI_DEVICE_ID_MEILHAUS_ME605F:
906 *name = ME6000_NAME_DEVICE_ME6000I16DIO;
907
908 break;
909
910 case PCI_DEVICE_ID_MEILHAUS_ME6074:
911 *name = ME6000_NAME_DEVICE_ME6000ISLE4DIO;
912
913 break;
914
915 case PCI_DEVICE_ID_MEILHAUS_ME6078:
916 *name = ME6000_NAME_DEVICE_ME6000ISLE8DIO;
917
918 break;
919
920 case PCI_DEVICE_ID_MEILHAUS_ME607F:
921 *name = ME6000_NAME_DEVICE_ME6000ISLE16DIO;
922
923 break;
924
925 case PCI_DEVICE_ID_MEILHAUS_ME6144:
926 *name = ME6000_NAME_DEVICE_ME61004DIO;
927
928 break;
929
930 case PCI_DEVICE_ID_MEILHAUS_ME6148:
931 *name = ME6000_NAME_DEVICE_ME61008DIO;
932
933 break;
934
935 case PCI_DEVICE_ID_MEILHAUS_ME614F:
936 *name = ME6000_NAME_DEVICE_ME610016DIO;
937
938 break;
939
940 case PCI_DEVICE_ID_MEILHAUS_ME6154:
941 *name = ME6000_NAME_DEVICE_ME6100I4DIO;
942
943 break;
944
945 case PCI_DEVICE_ID_MEILHAUS_ME6158:
946 *name = ME6000_NAME_DEVICE_ME6100I8DIO;
947
948 break;
949
950 case PCI_DEVICE_ID_MEILHAUS_ME615F:
951 *name = ME6000_NAME_DEVICE_ME6100I16DIO;
952
953 break;
954
955 case PCI_DEVICE_ID_MEILHAUS_ME6174:
956 *name = ME6000_NAME_DEVICE_ME6100ISLE4DIO;
957
958 break;
959
960 case PCI_DEVICE_ID_MEILHAUS_ME6178:
961 *name = ME6000_NAME_DEVICE_ME6100ISLE8DIO;
962
963 break;
964
965 case PCI_DEVICE_ID_MEILHAUS_ME617F:
966 *name = ME6000_NAME_DEVICE_ME6100ISLE16DIO;
967
968 break;
969
970 case PCI_DEVICE_ID_MEILHAUS_ME0630:
971 *name = ME0600_NAME_DEVICE_ME0630;
972
973 break;
974
975 case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
976 *name = ME8100_NAME_DEVICE_ME8100A;
977
978 break;
979
980 case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
981 *name = ME8100_NAME_DEVICE_ME8100B;
982
983 break;
984
985 case PCI_DEVICE_ID_MEILHAUS_ME0940:
986 *name = ME0900_NAME_DEVICE_ME0940;
987
988 break;
989
990 case PCI_DEVICE_ID_MEILHAUS_ME0950:
991 *name = ME0900_NAME_DEVICE_ME0950;
992
993 break;
994
995 case PCI_DEVICE_ID_MEILHAUS_ME0960:
996 *name = ME0900_NAME_DEVICE_ME0960;
997
998 break;
999/*
1000 case USB_DEVICE_ID_MEPHISTO_S1:
1001 *name = MEPHISTO_S1_NAME_DEVICE;
1002
1003 break;
1004*/
1005 default:
1006 *name = EMPTY_NAME_DEVICE;
1007 PERROR("Invalid PCI device id.\n");
1008
1009 return ME_ERRNO_INTERNAL;
1010 }
1011
1012 return ME_ERRNO_SUCCESS;
1013}
1014
1015static int medummy_query_number_subdevices(me_device_t * device, int *number)
1016{
1017 PDEBUG("executed.\n");
1018 return ME_ERRNO_DEVICE_UNPLUGGED;
1019}
1020
1021static int medummy_query_number_channels(me_device_t * device,
1022 int subdevice, int *number)
1023{
1024 PDEBUG("executed.\n");
1025 return ME_ERRNO_DEVICE_UNPLUGGED;
1026}
1027
1028static int medummy_query_number_ranges(me_device_t * device,
1029 int subdevice, int unit, int *count)
1030{
1031 PDEBUG("executed.\n");
1032 return ME_ERRNO_DEVICE_UNPLUGGED;
1033}
1034
1035static int medummy_query_subdevice_type(me_device_t * device,
1036 int subdevice, int *type, int *subtype)
1037{
1038 PDEBUG("executed.\n");
1039 return ME_ERRNO_DEVICE_UNPLUGGED;
1040}
1041
1042static int medummy_query_subdevice_caps(me_device_t * device,
1043 int subdevice, int *caps)
1044{
1045 PDEBUG("executed.\n");
1046 return ME_ERRNO_DEVICE_UNPLUGGED;
1047}
1048
1049static int medummy_query_subdevice_caps_args(me_device_t * device,
1050 int subdevice,
1051 int cap, int *args, int count)
1052{
1053 PDEBUG("executed.\n");
1054 return ME_ERRNO_NOT_SUPPORTED;
1055}
1056
1057static int medummy_query_subdevice_by_type(me_device_t * device,
1058 int start_subdevice,
1059 int type,
1060 int subtype, int *subdevice)
1061{
1062 PDEBUG("executed.\n");
1063 return ME_ERRNO_DEVICE_UNPLUGGED;
1064}
1065
1066static int medummy_query_range_by_min_max(me_device_t * device,
1067 int subdevice,
1068 int unit,
1069 int *min,
1070 int *max, int *maxdata, int *range)
1071{
1072 PDEBUG("executed.\n");
1073 return ME_ERRNO_DEVICE_UNPLUGGED;
1074}
1075
1076static int medummy_query_range_info(me_device_t * device,
1077 int subdevice,
1078 int range,
1079 int *unit, int *min, int *max, int *maxdata)
1080{
1081 PDEBUG("executed.\n");
1082 return ME_ERRNO_DEVICE_UNPLUGGED;
1083}
1084
1085int medummy_query_timer(me_device_t * device,
1086 int subdevice,
1087 int timer,
1088 int *base_frequency,
1089 uint64_t * min_ticks, uint64_t * max_ticks)
1090{
1091 PDEBUG("executed.\n");
1092 return ME_ERRNO_DEVICE_UNPLUGGED;
1093}
1094
1095static int medummy_query_version_device_driver(me_device_t * device,
1096 int *version)
1097{
1098 PDEBUG("executed.\n");
1099
1100 *version = ME_VERSION_DRIVER;
1101 return ME_ERRNO_SUCCESS;
1102}
1103
1104static void medummy_destructor(me_device_t * device)
1105{
1106 PDEBUG("executed.\n");
1107 kfree(device);
1108}
1109
1110static int init_device_info(unsigned short vendor_id,
1111 unsigned short device_id,
1112 unsigned int serial_no,
1113 int bus_type,
1114 int bus_no,
1115 int dev_no,
1116 int func_no, medummy_device_t * instance)
1117{
1118 PDEBUG("executed.\n");
1119
1120// instance->magic = MEDUMMY_MAGIC_NUMBER;
1121 instance->vendor_id = vendor_id;
1122 instance->device_id = device_id;
1123 instance->serial_no = serial_no;
1124 instance->bus_type = bus_type;
1125 instance->bus_no = bus_no;
1126 instance->dev_no = dev_no;
1127 instance->func_no = func_no;
1128
1129 return 0;
1130}
1131
1132static int medummy_config_load(me_device_t * device, struct file *filep,
1133 me_cfg_device_entry_t * config)
1134{
1135 PDEBUG("executed.\n");
1136 return ME_ERRNO_SUCCESS;
1137}
1138
1139static int init_device_instance(me_device_t * device)
1140{
1141 PDEBUG("executed.\n");
1142
1143 INIT_LIST_HEAD(&device->list);
1144
1145 device->me_device_io_irq_start = medummy_io_irq_start;
1146 device->me_device_io_irq_wait = medummy_io_irq_wait;
1147 device->me_device_io_irq_stop = medummy_io_irq_stop;
1148 device->me_device_io_reset_device = medummy_io_reset_device;
1149 device->me_device_io_reset_subdevice = medummy_io_reset_subdevice;
1150 device->me_device_io_single_config = medummy_io_single_config;
1151 device->me_device_io_single_read = medummy_io_single_read;
1152 device->me_device_io_single_write = medummy_io_single_write;
1153 device->me_device_io_stream_config = medummy_io_stream_config;
1154 device->me_device_io_stream_new_values = medummy_io_stream_new_values;
1155 device->me_device_io_stream_read = medummy_io_stream_read;
1156 device->me_device_io_stream_start = medummy_io_stream_start;
1157 device->me_device_io_stream_status = medummy_io_stream_status;
1158 device->me_device_io_stream_stop = medummy_io_stream_stop;
1159 device->me_device_io_stream_write = medummy_io_stream_write;
1160
1161 device->me_device_lock_device = medummy_lock_device;
1162 device->me_device_lock_subdevice = medummy_lock_subdevice;
1163
1164 device->me_device_query_description_device =
1165 medummy_query_description_device;
1166 device->me_device_query_info_device = medummy_query_info_device;
1167 device->me_device_query_name_device_driver =
1168 medummy_query_name_device_driver;
1169 device->me_device_query_name_device = medummy_query_name_device;
1170
1171 device->me_device_query_number_subdevices =
1172 medummy_query_number_subdevices;
1173 device->me_device_query_number_channels = medummy_query_number_channels;
1174 device->me_device_query_number_ranges = medummy_query_number_ranges;
1175
1176 device->me_device_query_range_by_min_max =
1177 medummy_query_range_by_min_max;
1178 device->me_device_query_range_info = medummy_query_range_info;
1179
1180 device->me_device_query_subdevice_type = medummy_query_subdevice_type;
1181 device->me_device_query_subdevice_by_type =
1182 medummy_query_subdevice_by_type;
1183 device->me_device_query_subdevice_caps = medummy_query_subdevice_caps;
1184 device->me_device_query_subdevice_caps_args =
1185 medummy_query_subdevice_caps_args;
1186
1187 device->me_device_query_timer = medummy_query_timer;
1188
1189 device->me_device_query_version_device_driver =
1190 medummy_query_version_device_driver;
1191
1192 device->me_device_destructor = medummy_destructor;
1193 device->me_device_config_load = medummy_config_load;
1194 return 0;
1195}
1196
1197me_device_t *medummy_constructor(unsigned short vendor_id,
1198 unsigned short device_id,
1199 unsigned int serial_no,
1200 int bus_type,
1201 int bus_no, int dev_no, int func_no)
1202{
1203 int result = 0;
1204 medummy_device_t *instance;
1205
1206 PDEBUG("executed.\n");
1207
1208 /* Allocate structure for device attributes */
1209 instance = kmalloc(sizeof(medummy_device_t), GFP_KERNEL);
1210
1211 if (!instance) {
1212 PERROR("Can't get memory for device instance.\n");
1213 return NULL;
1214 }
1215
1216 memset(instance, 0, sizeof(medummy_device_t));
1217
1218 /* Initialize device info */
1219 result = init_device_info(vendor_id,
1220 device_id,
1221 serial_no,
1222 bus_type, bus_no, dev_no, func_no, instance);
1223
1224 if (result) {
1225 PERROR("Cannot init baord info.\n");
1226 kfree(instance);
1227 return NULL;
1228 }
1229
1230 /* Initialize device instance */
1231 result = init_device_instance((me_device_t *) instance);
1232
1233 if (result) {
1234 PERROR("Cannot init baord info.\n");
1235 kfree(instance);
1236 return NULL;
1237 }
1238
1239 return (me_device_t *) instance;
1240}
1241
1242// Init and exit of module.
1243
1244static int __init dummy_init(void)
1245{
1246 PDEBUG("executed.\n");
1247 return 0;
1248}
1249
1250static void __exit dummy_exit(void)
1251{
1252 PDEBUG("executed.\n");
1253}
1254
1255module_init(dummy_init);
1256
1257module_exit(dummy_exit);
1258
1259// Administrative stuff for modinfo.
1260MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
1261MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-DUMMY Devices");
1262MODULE_SUPPORTED_DEVICE("Meilhaus ME-DUMMY Devices");
1263MODULE_LICENSE("GPL");
1264
1265// Export the constructor.
1266EXPORT_SYMBOL(medummy_constructor);
diff --git a/drivers/staging/meilhaus/medummy.h b/drivers/staging/meilhaus/medummy.h
new file mode 100644
index 000000000000..717000ff6c1c
--- /dev/null
+++ b/drivers/staging/meilhaus/medummy.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File : medummy.h
5 * Author : GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
6 */
7
8#ifndef _MEDUMMY_H_
9#define _MEDUMMY_H_
10
11#include "metypes.h"
12#include "medefines.h"
13#include "medevice.h"
14
15#ifdef __KERNEL__
16
17#define MEDUMMY_MAGIC_NUMBER 0xDDDD
18
19typedef struct medummy_device {
20 me_device_t base; /**< The Meilhaus device base class. */
21// int magic; /**< The magic number of the structure */
22 unsigned short vendor_id; /**< Vendor ID */
23 unsigned short device_id; /**< Device ID */
24 unsigned int serial_no; /**< Serial number of the device */
25 int bus_type; /**< Bus type */
26 int bus_no; /**< Bus number */
27 int dev_no; /**< Device number */
28 int func_no; /**< Function number */
29} medummy_device_t;
30
31me_device_t *medummy_constructor(unsigned short vendor_id,
32 unsigned short device_id,
33 unsigned int serial_no,
34 int bus_type,
35 int bus_no,
36 int dev_no,
37 int func_no) __attribute__ ((weak));
38
39#endif
40#endif
diff --git a/drivers/staging/meilhaus/meerror.h b/drivers/staging/meilhaus/meerror.h
new file mode 100644
index 000000000000..9eda4bf907ba
--- /dev/null
+++ b/drivers/staging/meilhaus/meerror.h
@@ -0,0 +1,100 @@
1/*
2 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File : meerror.h
5 * Author : GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
6 * Author : KG (Krzysztof Gantzke) <k.gantzke@meilhaus.de>
7 */
8
9#ifndef _MEERROR_H_
10#define _MEERROR_H_
11
12extern char *meErrorMsgTable[];
13
14#define ME_ERRNO_SUCCESS 0
15#define ME_ERRNO_INVALID_DEVICE 1
16#define ME_ERRNO_INVALID_SUBDEVICE 2
17#define ME_ERRNO_INVALID_CHANNEL 3
18#define ME_ERRNO_INVALID_SINGLE_CONFIG 4
19#define ME_ERRNO_INVALID_REF 5
20#define ME_ERRNO_INVALID_TRIG_CHAN 6
21#define ME_ERRNO_INVALID_TRIG_TYPE 7
22#define ME_ERRNO_INVALID_TRIG_EDGE 8
23#define ME_ERRNO_INVALID_TIMEOUT 9
24#define ME_ERRNO_INVALID_FLAGS 10
25#define ME_ERRNO_OPEN 11
26#define ME_ERRNO_CLOSE 12
27#define ME_ERRNO_NOT_OPEN 13
28#define ME_ERRNO_INVALID_DIR 14
29#define ME_ERRNO_PREVIOUS_CONFIG 15
30#define ME_ERRNO_NOT_SUPPORTED 16
31#define ME_ERRNO_SUBDEVICE_TYPE 17
32#define ME_ERRNO_USER_BUFFER_SIZE 18
33#define ME_ERRNO_LOCKED 19
34#define ME_ERRNO_NOMORE_SUBDEVICE_TYPE 20
35#define ME_ERRNO_TIMEOUT 21
36#define ME_ERRNO_SIGNAL 22
37#define ME_ERRNO_INVALID_IRQ_SOURCE 23
38#define ME_ERRNO_THREAD_RUNNING 24
39#define ME_ERRNO_START_THREAD 25
40#define ME_ERRNO_CANCEL_THREAD 26
41#define ME_ERRNO_NO_CALLBACK 27
42#define ME_ERRNO_USED 28
43#define ME_ERRNO_INVALID_UNIT 29
44#define ME_ERRNO_INVALID_MIN_MAX 30
45#define ME_ERRNO_NO_RANGE 31
46#define ME_ERRNO_INVALID_RANGE 32
47#define ME_ERRNO_SUBDEVICE_BUSY 33
48#define ME_ERRNO_INVALID_LOCK 34
49#define ME_ERRNO_INVALID_SWITCH 35
50#define ME_ERRNO_INVALID_ERROR_MSG_COUNT 36
51#define ME_ERRNO_INVALID_STREAM_CONFIG 37
52#define ME_ERRNO_INVALID_CONFIG_LIST_COUNT 38
53#define ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE 39
54#define ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE 40
55#define ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN 41
56#define ME_ERRNO_INVALID_ACQ_START_TIMEOUT 42
57#define ME_ERRNO_INVALID_ACQ_START_ARG 43
58#define ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE 44
59#define ME_ERRNO_INVALID_SCAN_START_ARG 45
60#define ME_ERRNO_INVALID_CONV_START_TRIG_TYPE 46
61#define ME_ERRNO_INVALID_CONV_START_ARG 47
62#define ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE 48
63#define ME_ERRNO_INVALID_SCAN_STOP_ARG 49
64#define ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE 50
65#define ME_ERRNO_INVALID_ACQ_STOP_ARG 51
66#define ME_ERRNO_SUBDEVICE_NOT_RUNNING 52
67#define ME_ERRNO_INVALID_READ_MODE 53
68#define ME_ERRNO_INVALID_VALUE_COUNT 54
69#define ME_ERRNO_INVALID_WRITE_MODE 55
70#define ME_ERRNO_INVALID_TIMER 56
71#define ME_ERRNO_DEVICE_UNPLUGGED 57
72#define ME_ERRNO_USED_INTERNAL 58
73#define ME_ERRNO_INVALID_DUTY_CYCLE 59
74#define ME_ERRNO_INVALID_WAIT 60
75#define ME_ERRNO_CONNECT_REMOTE 61
76#define ME_ERRNO_COMMUNICATION 62
77#define ME_ERRNO_INVALID_SINGLE_LIST 63
78#define ME_ERRNO_INVALID_MODULE_TYPE 64
79#define ME_ERRNO_INVALID_START_MODE 65
80#define ME_ERRNO_INVALID_STOP_MODE 66
81#define ME_ERRNO_INVALID_FIFO_IRQ_THRESHOLD 67
82#define ME_ERRNO_INVALID_POINTER 68
83#define ME_ERRNO_CREATE_EVENT 69
84#define ME_ERRNO_LACK_OF_RESOURCES 70
85#define ME_ERRNO_CANCELLED 71
86#define ME_ERRNO_RING_BUFFER_OVERFLOW 72
87#define ME_ERRNO_RING_BUFFER_UNDEFFLOW 73
88#define ME_ERRNO_INVALID_IRQ_EDGE 74
89#define ME_ERRNO_INVALID_IRQ_ARG 75
90#define ME_ERRNO_INVALID_CAP 76
91#define ME_ERRNO_INVALID_CAP_ARG_COUNT 77
92#define ME_ERRNO_INTERNAL 78
93
94/** New error for range check */
95#define ME_ERRNO_VALUE_OUT_OF_RANGE 79
96#define ME_ERRNO_FIFO_BUFFER_OVERFLOW 80
97#define ME_ERRNO_FIFO_BUFFER_UNDEFFLOW 81
98
99#define ME_ERRNO_INVALID_ERROR_NUMBER 82
100#endif
diff --git a/drivers/staging/meilhaus/mefirmware.c b/drivers/staging/meilhaus/mefirmware.c
new file mode 100644
index 000000000000..c07d202e8cb5
--- /dev/null
+++ b/drivers/staging/meilhaus/mefirmware.c
@@ -0,0 +1,137 @@
1/**
2 * @file mefirmware.c
3 *
4 * @brief Implements the firmware handling.
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 * Copyright (C) 2007 by Krzysztof Gantzke k.gantzke@meilhaus.de *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 ***************************************************************************/
29
30#ifndef __KERNEL__
31# define __KERNEL__
32#endif
33
34#ifndef KBUILD_MODNAME
35# define KBUILD_MODNAME KBUILD_STR(mefirmware)
36#endif
37
38#include <linux/pci.h>
39#include <linux/delay.h>
40
41#include <linux/firmware.h>
42
43#include "meplx_reg.h"
44#include "medebug.h"
45
46#include "mefirmware.h"
47
48int me_xilinx_download(unsigned long register_base_control,
49 unsigned long register_base_data,
50 struct device *dev, const char *firmware_name)
51{
52 int err = ME_ERRNO_FIRMWARE;
53 uint32_t value = 0;
54 int idx = 0;
55
56 const struct firmware *fw;
57
58 PDEBUG("executed.\n");
59
60 if (!firmware_name) {
61 PERROR("Request for firmware failed. No name provided. \n");
62 return err;
63 }
64
65 PINFO("Request '%s' firmware.\n", firmware_name);
66 err = request_firmware(&fw, firmware_name, dev);
67
68 if (err) {
69 PERROR("Request for firmware failed.\n");
70 return err;
71 }
72 // Set PLX local interrupt 2 polarity to high.
73 // Interrupt is thrown by init pin of xilinx.
74 outl(PLX_INTCSR_LOCAL_INT2_POL, register_base_control + PLX_INTCSR);
75
76 // Set /CS and /WRITE of the Xilinx
77 value = inl(register_base_control + PLX_ICR);
78 value |= ME_FIRMWARE_CS_WRITE;
79 outl(value, register_base_control + PLX_ICR);
80
81 // Init Xilinx with CS1
82 inl(register_base_data + ME_XILINX_CS1_REG);
83
84 // Wait for init to complete
85 udelay(20);
86
87 // Checkl /INIT pin
88 if (!
89 (inl(register_base_control + PLX_INTCSR) &
90 PLX_INTCSR_LOCAL_INT2_STATE)) {
91 PERROR("Can't init Xilinx.\n");
92 release_firmware(fw);
93 return -EIO;
94 }
95 // Reset /CS and /WRITE of the Xilinx
96 value = inl(register_base_control + PLX_ICR);
97 value &= ~ME_FIRMWARE_CS_WRITE;
98 outl(value, register_base_control + PLX_ICR);
99
100 // Download Xilinx firmware
101 udelay(10);
102
103 for (idx = 0; idx < fw->size; idx++) {
104 outl(fw->data[idx], register_base_data);
105#ifdef ME6000_v2_4
106/// This checking only for board's version 2.4
107 // Check if BUSY flag is set (low = ready, high = busy)
108 if (inl(register_base_control + PLX_ICR) &
109 ME_FIRMWARE_BUSY_FLAG) {
110 PERROR("Xilinx is still busy (idx = %d)\n", idx);
111 release_firmware(fw);
112 return -EIO;
113 }
114#endif //ME6000_v2_4
115 }
116 PDEBUG("Download finished. %d bytes written to PLX.\n", idx);
117
118 // If done flag is high download was successful
119 if (inl(register_base_control + PLX_ICR) & ME_FIRMWARE_DONE_FLAG) {
120 PDEBUG("SUCCESS. Done flag is set.\n");
121 } else {
122 PERROR("FAILURE. DONE flag is not set.\n");
123 release_firmware(fw);
124 return -EIO;
125 }
126
127 // Set /CS and /WRITE
128 value = inl(register_base_control + PLX_ICR);
129 value |= ME_FIRMWARE_CS_WRITE;
130 outl(value, register_base_control + PLX_ICR);
131
132 PDEBUG("Enable interrupts on the PCI interface.\n");
133 outl(ME_PLX_PCI_ACTIVATE, register_base_control + PLX_INTCSR);
134 release_firmware(fw);
135
136 return 0;
137}
diff --git a/drivers/staging/meilhaus/mefirmware.h b/drivers/staging/meilhaus/mefirmware.h
new file mode 100644
index 000000000000..a2685080c97b
--- /dev/null
+++ b/drivers/staging/meilhaus/mefirmware.h
@@ -0,0 +1,57 @@
1/**
2 * @file mefirmware.h
3 *
4 * @brief Definitions of the firmware handling functions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Krzysztof Gantzke (k.gantzke@meilhaus.de)
7 */
8
9/***************************************************************************
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) *
11 * Copyright (C) 2007 by Krzysztof Gantzke k.gantzke@meilhaus.de *
12 * *
13 * This program 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 *
25 * Free Software Foundation, Inc., *
26 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
27 ***************************************************************************/
28
29#ifndef _MEFIRMWARE_H
30# define _MEFIRMWARE_H
31
32# ifdef __KERNEL__
33
34#define ME_ERRNO_FIRMWARE -1
35
36/**
37* Registry
38*/
39#define ME_XILINX_CS1_REG 0x00C8
40
41/**
42* Flags (bits)
43*/
44
45#define ME_FIRMWARE_BUSY_FLAG 0x00000020
46#define ME_FIRMWARE_DONE_FLAG 0x00000004
47#define ME_FIRMWARE_CS_WRITE 0x00000100
48
49#define ME_PLX_PCI_ACTIVATE 0x43
50
51int me_xilinx_download(unsigned long register_base_control,
52 unsigned long register_base_data,
53 struct device *dev, const char *firmware_name);
54
55# endif //__KERNEL__
56
57#endif //_MEFIRMWARE_H
diff --git a/drivers/staging/meilhaus/meids.h b/drivers/staging/meilhaus/meids.h
new file mode 100644
index 000000000000..b3e757cbdda6
--- /dev/null
+++ b/drivers/staging/meilhaus/meids.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File : meids.h
5 * Author : GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
6 */
7
8#ifndef _MEIDS_H_
9#define _MEIDS_H_
10
11#ifdef __KERNEL__
12
13/*=============================================================================
14 Driver names
15 ===========================================================================*/
16
17#define MEMAIN_NAME "memain"
18#define ME1000_NAME "me1000"
19#define ME1400_NAME "me1400"
20#define ME1600_NAME "me1600"
21#define ME4600_NAME "me4600"
22#define ME6000_NAME "me6000"
23#define ME0600_NAME "me0600" //"me630"
24#define ME8100_NAME "me8100"
25#define ME8200_NAME "me8200"
26#define ME0900_NAME "me0900" //"me9x"
27//#define MEPHISTO_S1_NAME "mephisto_s1"
28#define MEDUMMY_NAME "medummy"
29
30#endif
31#endif
diff --git a/drivers/staging/meilhaus/meinternal.h b/drivers/staging/meilhaus/meinternal.h
new file mode 100644
index 000000000000..8d126b4905a7
--- /dev/null
+++ b/drivers/staging/meilhaus/meinternal.h
@@ -0,0 +1,363 @@
1/*
2 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File : meinternal.h
5 * Author : GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
6 */
7
8#ifndef _MEINTERNAL_H_
9#define _MEINTERNAL_H_
10
11/*=============================================================================
12 PCI Vendor IDs
13 ===========================================================================*/
14
15#define PCI_VENDOR_ID_MEILHAUS 0x1402
16
17/*=============================================================================
18 PCI Device IDs
19 ===========================================================================*/
20
21#define PCI_DEVICE_ID_MEILHAUS_ME1000 0x1000
22#define PCI_DEVICE_ID_MEILHAUS_ME1000_A 0x100A
23#define PCI_DEVICE_ID_MEILHAUS_ME1000_B 0x100B
24
25#define PCI_DEVICE_ID_MEILHAUS_ME1400 0x1400
26#define PCI_DEVICE_ID_MEILHAUS_ME140A 0x140A
27#define PCI_DEVICE_ID_MEILHAUS_ME140B 0x140B
28#define PCI_DEVICE_ID_MEILHAUS_ME14E0 0x14E0
29#define PCI_DEVICE_ID_MEILHAUS_ME14EA 0x14EA
30#define PCI_DEVICE_ID_MEILHAUS_ME14EB 0x14EB
31#define PCI_DEVICE_ID_MEILHAUS_ME140C 0X140C
32#define PCI_DEVICE_ID_MEILHAUS_ME140D 0X140D
33
34#define PCI_DEVICE_ID_MEILHAUS_ME1600_4U 0x1604 // 4 voltage outputs
35#define PCI_DEVICE_ID_MEILHAUS_ME1600_8U 0x1608 // 8 voltage outputs
36#define PCI_DEVICE_ID_MEILHAUS_ME1600_12U 0x160C // 12 voltage outputs
37#define PCI_DEVICE_ID_MEILHAUS_ME1600_16U 0x160F // 16 voltage outputs
38#define PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I 0x168F // 16 voltage/8 current o.
39
40#define PCI_DEVICE_ID_MEILHAUS_ME4610 0x4610 // Jekyll
41
42#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 // Low Cost version
43
44#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 // Standard version
45#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 // Isolated version
46#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662 // Standard version with Sample and Hold
47#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663 // Isolated version with Sample and Hold
48
49#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670 // Standard version
50#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671 // Isolated version
51#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672 // Standard version with Sample and Hold
52#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673 // Isolated version with Sample and Hold
53
54#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680 // Standard version
55#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681 // Isolated version
56#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 // Standard version with Sample and Hold
57#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 // Isolated version with Sample and Hold
58
59/* ME6000 standard version */
60#define PCI_DEVICE_ID_MEILHAUS_ME6004 0x6004
61#define PCI_DEVICE_ID_MEILHAUS_ME6008 0x6008
62#define PCI_DEVICE_ID_MEILHAUS_ME600F 0x600F
63
64/* ME6000 isolated version */
65#define PCI_DEVICE_ID_MEILHAUS_ME6014 0x6014
66#define PCI_DEVICE_ID_MEILHAUS_ME6018 0x6018
67#define PCI_DEVICE_ID_MEILHAUS_ME601F 0x601F
68
69/* ME6000 isle version */
70#define PCI_DEVICE_ID_MEILHAUS_ME6034 0x6034
71#define PCI_DEVICE_ID_MEILHAUS_ME6038 0x6038
72#define PCI_DEVICE_ID_MEILHAUS_ME603F 0x603F
73
74/* ME6000 standard version with DIO */
75#define PCI_DEVICE_ID_MEILHAUS_ME6044 0x6044
76#define PCI_DEVICE_ID_MEILHAUS_ME6048 0x6048
77#define PCI_DEVICE_ID_MEILHAUS_ME604F 0x604F
78
79/* ME6000 isolated version with DIO */
80#define PCI_DEVICE_ID_MEILHAUS_ME6054 0x6054
81#define PCI_DEVICE_ID_MEILHAUS_ME6058 0x6058
82#define PCI_DEVICE_ID_MEILHAUS_ME605F 0x605F
83
84/* ME6000 isle version with DIO */
85#define PCI_DEVICE_ID_MEILHAUS_ME6074 0x6074
86#define PCI_DEVICE_ID_MEILHAUS_ME6078 0x6078
87#define PCI_DEVICE_ID_MEILHAUS_ME607F 0x607F
88
89/* ME6100 standard version */
90#define PCI_DEVICE_ID_MEILHAUS_ME6104 0x6104
91#define PCI_DEVICE_ID_MEILHAUS_ME6108 0x6108
92#define PCI_DEVICE_ID_MEILHAUS_ME610F 0x610F
93
94/* ME6100 isolated version */
95#define PCI_DEVICE_ID_MEILHAUS_ME6114 0x6114
96#define PCI_DEVICE_ID_MEILHAUS_ME6118 0x6118
97#define PCI_DEVICE_ID_MEILHAUS_ME611F 0x611F
98
99/* ME6100 isle version */
100#define PCI_DEVICE_ID_MEILHAUS_ME6134 0x6134
101#define PCI_DEVICE_ID_MEILHAUS_ME6138 0x6138
102#define PCI_DEVICE_ID_MEILHAUS_ME613F 0x613F
103
104/* ME6100 standard version with DIO */
105#define PCI_DEVICE_ID_MEILHAUS_ME6144 0x6144
106#define PCI_DEVICE_ID_MEILHAUS_ME6148 0x6148
107#define PCI_DEVICE_ID_MEILHAUS_ME614F 0x614F
108
109/* ME6100 isolated version with DIO */
110#define PCI_DEVICE_ID_MEILHAUS_ME6154 0x6154
111#define PCI_DEVICE_ID_MEILHAUS_ME6158 0x6158
112#define PCI_DEVICE_ID_MEILHAUS_ME615F 0x615F
113
114/* ME6100 isle version with DIO */
115#define PCI_DEVICE_ID_MEILHAUS_ME6174 0x6174
116#define PCI_DEVICE_ID_MEILHAUS_ME6178 0x6178
117#define PCI_DEVICE_ID_MEILHAUS_ME617F 0x617F
118
119/* ME6200 isolated version with DIO */
120#define PCI_DEVICE_ID_MEILHAUS_ME6259 0x6259
121
122/* ME6300 isolated version with DIO */
123#define PCI_DEVICE_ID_MEILHAUS_ME6359 0x6359
124
125/* ME0630 */
126#define PCI_DEVICE_ID_MEILHAUS_ME0630 0x0630
127
128/* ME8100 */
129#define PCI_DEVICE_ID_MEILHAUS_ME8100_A 0x810A
130#define PCI_DEVICE_ID_MEILHAUS_ME8100_B 0x810B
131
132/* ME8200 */
133#define PCI_DEVICE_ID_MEILHAUS_ME8200_A 0x820A
134#define PCI_DEVICE_ID_MEILHAUS_ME8200_B 0x820B
135
136/* ME0900 */
137#define PCI_DEVICE_ID_MEILHAUS_ME0940 0x0940
138#define PCI_DEVICE_ID_MEILHAUS_ME0950 0x0950
139#define PCI_DEVICE_ID_MEILHAUS_ME0960 0x0960
140
141
142/*=============================================================================
143 USB Vendor IDs
144 ===========================================================================*/
145
146//#define USB_VENDOR_ID_MEPHISTO_S1 0x0403
147
148
149/*=============================================================================
150 USB Device IDs
151 ===========================================================================*/
152
153//#define USB_DEVICE_ID_MEPHISTO_S1 0xDCD0
154
155
156/* ME-1000 defines */
157#define ME1000_NAME_DRIVER "ME-1000"
158
159#define ME1000_NAME_DEVICE_ME1000 "ME-1000"
160
161#define ME1000_DESCRIPTION_DEVICE_ME1000 "ME-1000 device, 128 digital i/o lines."
162
163/* ME-1400 defines */
164#define ME1400_NAME_DRIVER "ME-1400"
165
166#define ME1400_NAME_DEVICE_ME1400 "ME-1400"
167#define ME1400_NAME_DEVICE_ME1400E "ME-1400E"
168#define ME1400_NAME_DEVICE_ME1400A "ME-1400A"
169#define ME1400_NAME_DEVICE_ME1400EA "ME-1400EA"
170#define ME1400_NAME_DEVICE_ME1400B "ME-1400B"
171#define ME1400_NAME_DEVICE_ME1400EB "ME-1400EB"
172#define ME1400_NAME_DEVICE_ME1400C "ME-1400C"
173#define ME1400_NAME_DEVICE_ME1400D "ME-1400D"
174
175#define ME1400_DESCRIPTION_DEVICE_ME1400 "ME-1400 device, 24 digital i/o lines."
176#define ME1400_DESCRIPTION_DEVICE_ME1400E "ME-1400E device, 24 digital i/o lines."
177#define ME1400_DESCRIPTION_DEVICE_ME1400A "ME-1400A device, 24 digital i/o lines, 3 counters."
178#define ME1400_DESCRIPTION_DEVICE_ME1400EA "ME-1400EA device, 24 digital i/o lines, 3 counters."
179#define ME1400_DESCRIPTION_DEVICE_ME1400B "ME-1400B device, 48 digital i/o lines, 6 counters."
180#define ME1400_DESCRIPTION_DEVICE_ME1400EB "ME-1400EB device, 48 digital i/o lines, 6 counters."
181#define ME1400_DESCRIPTION_DEVICE_ME1400C "ME-1400C device, 24 digital i/o lines, 15 counters."
182#define ME1400_DESCRIPTION_DEVICE_ME1400D "ME-1400D device, 48 digital i/o lines, 30 counters."
183
184/* ME-1600 defines */
185#define ME1600_NAME_DRIVER "ME-1600"
186
187#define ME1600_NAME_DEVICE_ME16004U "ME-1600/4U"
188#define ME1600_NAME_DEVICE_ME16008U "ME-1600/8U"
189#define ME1600_NAME_DEVICE_ME160012U "ME-1600/12U"
190#define ME1600_NAME_DEVICE_ME160016U "ME-1600/16U"
191#define ME1600_NAME_DEVICE_ME160016U8I "ME-1600/16U8I"
192
193#define ME1600_DESCRIPTION_DEVICE_ME16004U "ME-1600/4U device, 4 voltage outputs."
194#define ME1600_DESCRIPTION_DEVICE_ME16008U "ME-1600/8U device, 8 voltage outputs."
195#define ME1600_DESCRIPTION_DEVICE_ME160012U "ME-1600/12U device, 12 voltage outputs."
196#define ME1600_DESCRIPTION_DEVICE_ME160016U "ME-1600/16U device, 16 voltage outputs."
197#define ME1600_DESCRIPTION_DEVICE_ME160016U8I "ME-1600/16U8I device, 16 voltage, 8 current outputs."
198
199/* ME-4000 defines */
200#define ME4600_NAME_DRIVER "ME-4600"
201
202#define ME4600_NAME_DEVICE_ME4610 "ME-4610"
203#define ME4600_NAME_DEVICE_ME4650 "ME-4650"
204#define ME4600_NAME_DEVICE_ME4660 "ME-4660"
205#define ME4600_NAME_DEVICE_ME4660I "ME-4660I"
206#define ME4600_NAME_DEVICE_ME4660S "ME-4660S"
207#define ME4600_NAME_DEVICE_ME4660IS "ME-4660IS"
208#define ME4600_NAME_DEVICE_ME4670 "ME-4670"
209#define ME4600_NAME_DEVICE_ME4670I "ME-4670I"
210#define ME4600_NAME_DEVICE_ME4670S "ME-4670S"
211#define ME4600_NAME_DEVICE_ME4670IS "ME-4670IS"
212#define ME4600_NAME_DEVICE_ME4680 "ME-4680"
213#define ME4600_NAME_DEVICE_ME4680I "ME-4680I"
214#define ME4600_NAME_DEVICE_ME4680S "ME-4680S"
215#define ME4600_NAME_DEVICE_ME4680IS "ME-4680IS"
216
217#define ME4600_DESCRIPTION_DEVICE_ME4610 "ME-4610 device, 16 streaming analog inputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
218#define ME4600_DESCRIPTION_DEVICE_ME4650 "ME-4650 device, 16 streaming analog inputs, 32 digital i/o lines, 1 external interrupt."
219#define ME4600_DESCRIPTION_DEVICE_ME4660 "ME-4660 device, 16 streaming analog inputs, 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
220#define ME4600_DESCRIPTION_DEVICE_ME4660I "ME-4660I opto isolated device, 16 streaming analog inputs, 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
221#define ME4600_DESCRIPTION_DEVICE_ME4660S "ME-4660 device, 16 streaming analog inputs (8 S&H), 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
222#define ME4600_DESCRIPTION_DEVICE_ME4660IS "ME-4660I opto isolated device, 16 streaming analog inputs (8 S&H), 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
223#define ME4600_DESCRIPTION_DEVICE_ME4670 "ME-4670 device, 32 streaming analog inputs, 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
224#define ME4600_DESCRIPTION_DEVICE_ME4670I "ME-4670I opto isolated device, 32 streaming analog inputs, 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
225#define ME4600_DESCRIPTION_DEVICE_ME4670S "ME-4670S device, 32 streaming analog inputs (8 S&H), 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
226#define ME4600_DESCRIPTION_DEVICE_ME4670IS "ME-4670IS opto isolated device, 32 streaming analog inputs (8 S&H), 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
227#define ME4600_DESCRIPTION_DEVICE_ME4680 "ME-4680 device, 32 streaming analog inputs, 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
228#define ME4600_DESCRIPTION_DEVICE_ME4680I "ME-4680I opto isolated device, 32 streaming analog inputs, 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
229#define ME4600_DESCRIPTION_DEVICE_ME4680S "ME-4680S device, 32 streaming analog inputs, 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
230#define ME4600_DESCRIPTION_DEVICE_ME4680IS "ME-4680IS opto isolated device, 32 streaming analog inputs (8 S&H), 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
231
232/* ME-6000 defines */
233#define ME6000_NAME_DRIVER "ME-6000"
234
235#define ME6000_NAME_DEVICE_ME60004 "ME-6000/4"
236#define ME6000_NAME_DEVICE_ME60008 "ME-6000/8"
237#define ME6000_NAME_DEVICE_ME600016 "ME-6000/16"
238#define ME6000_NAME_DEVICE_ME6000I4 "ME-6000I/4"
239#define ME6000_NAME_DEVICE_ME6000I8 "ME-6000I/8"
240#define ME6000_NAME_DEVICE_ME6000I16 "ME-6000I/16"
241#define ME6000_NAME_DEVICE_ME6000ISLE4 "ME-6000ISLE/4"
242#define ME6000_NAME_DEVICE_ME6000ISLE8 "ME-6000ISLE/8"
243#define ME6000_NAME_DEVICE_ME6000ISLE16 "ME-6000ISLE/16"
244#define ME6000_NAME_DEVICE_ME61004 "ME-6100/4"
245#define ME6000_NAME_DEVICE_ME61008 "ME-6100/8"
246#define ME6000_NAME_DEVICE_ME610016 "ME-6100/16"
247#define ME6000_NAME_DEVICE_ME6100I4 "ME-6100I/4"
248#define ME6000_NAME_DEVICE_ME6100I8 "ME-6100I/8"
249#define ME6000_NAME_DEVICE_ME6100I16 "ME-6100I/16"
250#define ME6000_NAME_DEVICE_ME6100ISLE4 "ME-6100ISLE/4"
251#define ME6000_NAME_DEVICE_ME6100ISLE8 "ME-6100ISLE/8"
252#define ME6000_NAME_DEVICE_ME6100ISLE16 "ME-6100ISLE/16"
253#define ME6000_NAME_DEVICE_ME60004DIO "ME-6000/4/DIO"
254#define ME6000_NAME_DEVICE_ME60008DIO "ME-6000/8/DIO"
255#define ME6000_NAME_DEVICE_ME600016DIO "ME-6000/16/DIO"
256#define ME6000_NAME_DEVICE_ME6000I4DIO "ME-6000I/4/DIO"
257#define ME6000_NAME_DEVICE_ME6000I8DIO "ME-6000I/8/DIO"
258#define ME6000_NAME_DEVICE_ME6000I16DIO "ME-6000I/16/DIO"
259#define ME6000_NAME_DEVICE_ME6000ISLE4DIO "ME-6000ISLE/4/DIO"
260#define ME6000_NAME_DEVICE_ME6000ISLE8DIO "ME-6000ISLE/8/DIO"
261#define ME6000_NAME_DEVICE_ME6000ISLE16DIO "ME-6000ISLE/16/DIO"
262#define ME6000_NAME_DEVICE_ME61004DIO "ME-6100/4/DIO"
263#define ME6000_NAME_DEVICE_ME61008DIO "ME-6100/8/DIO"
264#define ME6000_NAME_DEVICE_ME610016DIO "ME-6100/16/DIO"
265#define ME6000_NAME_DEVICE_ME6100I4DIO "ME-6100I/4/DIO"
266#define ME6000_NAME_DEVICE_ME6100I8DIO "ME-6100I/8/DIO"
267#define ME6000_NAME_DEVICE_ME6100I16DIO "ME-6100I/16/DIO"
268#define ME6000_NAME_DEVICE_ME6100ISLE4DIO "ME-6100ISLE/4/DIO"
269#define ME6000_NAME_DEVICE_ME6100ISLE8DIO "ME-6100ISLE/8/DIO"
270#define ME6000_NAME_DEVICE_ME6100ISLE16DIO "ME-6100ISLE/16/DIO"
271#define ME6000_NAME_DEVICE_ME6200I9DIO "ME-6200I/9/DIO"
272#define ME6000_NAME_DEVICE_ME6300I9DIO "ME-6300I/9/DIO"
273
274#define ME6000_DESCRIPTION_DEVICE_ME60004 "ME-6000/4 device, 4 single analog outputs."
275#define ME6000_DESCRIPTION_DEVICE_ME60008 "ME-6000/8 device, 8 single analog outputs"
276#define ME6000_DESCRIPTION_DEVICE_ME600016 "ME-6000/16 device, 16 single analog outputs"
277#define ME6000_DESCRIPTION_DEVICE_ME6000I4 "ME-6000I/4 isolated device, 4 single analog outputs"
278#define ME6000_DESCRIPTION_DEVICE_ME6000I8 "ME-6000I/8 isolated device, 8 single analog outputs"
279#define ME6000_DESCRIPTION_DEVICE_ME6000I16 "ME-6000I/16 isolated device, 16 single analog outputs"
280#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE4 "ME-6000ISLE/4 isle device, 4 single analog outputs"
281#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE8 "ME-6000ISLE/8 isle device, 8 single analog outputs"
282#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE16 "ME-6000ISLE/16 isle device, 16 single analog outputs"
283#define ME6000_DESCRIPTION_DEVICE_ME61004 "ME-6100/4 device, 4 streaming analog outputs."
284#define ME6000_DESCRIPTION_DEVICE_ME61008 "ME-6100/8 device, 4 streaming, 4 single analog outputs."
285#define ME6000_DESCRIPTION_DEVICE_ME610016 "ME-6100/16 device, 4 streaming, 12 single analog outputs."
286#define ME6000_DESCRIPTION_DEVICE_ME6100I4 "ME-6100I/4 isolated device, 4 streaming analog outputs."
287#define ME6000_DESCRIPTION_DEVICE_ME6100I8 "ME-6100I/8 isolated device, 4 streaming, 4 single analog outputs."
288#define ME6000_DESCRIPTION_DEVICE_ME6100I16 "ME-6100I/16 isolated device, 4 streaming, 12 single analog outputs."
289#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE4 "ME-6100ISLE/4 isle device, 4 streaming analog outputs."
290#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE8 "ME-6100ISLE/8 isle device, 4 streaming, 4 single analog outputs."
291#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE16 "ME-6100ISLE/16 isle device, 4 streaming, 12 single analog outputs."
292#define ME6000_DESCRIPTION_DEVICE_ME60004DIO "ME-6000/4/DIO device, 4 single analog outputs, 16 digital i/o lines."
293#define ME6000_DESCRIPTION_DEVICE_ME60008DIO "ME-6000/8/DIO device, 8 single analog outputs, 16 digital i/o lines."
294#define ME6000_DESCRIPTION_DEVICE_ME600016DIO "ME-6000/16/DIO device, 8 single analog outputs, 16 digital i/o lines."
295#define ME6000_DESCRIPTION_DEVICE_ME6000I4DIO "ME-6000I/4/DIO isolated device, 4 single analog outputs, 16 digital i/o lines."
296#define ME6000_DESCRIPTION_DEVICE_ME6000I8DIO "ME-6000I/8/DIO isolated device, 8 single analog outputs, 16 digital i/o lines."
297#define ME6000_DESCRIPTION_DEVICE_ME6000I16DIO "ME-6000I/16/DIO isolated device, 16 single analog outputs, 16 digital i/o lines."
298#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE4DIO "ME-6000ISLE/4/DIO isle device, 4 single analog outputs, 16 digital i/o lines."
299#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE8DIO "ME-6000ISLE/8/DIO isle device, 8 single analog outputs, 16 digital i/o lines."
300#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE16DIO "ME-6000ISLE/16/DIO isle device, 16 single analog outputs, 16 digital i/o lines."
301#define ME6000_DESCRIPTION_DEVICE_ME61004DIO "ME-6100/4/DIO device, 4 streaming analog outputs, 16 digital i/o lines."
302#define ME6000_DESCRIPTION_DEVICE_ME61008DIO "ME-6100/8/DIO device, 4 streaming, 4 single analog outputs, 16 digital i/o lines."
303#define ME6000_DESCRIPTION_DEVICE_ME610016DIO "ME-6100/16/DIO device, 4 streaming, 12 single analog outputs, 16 digital i/o lines."
304#define ME6000_DESCRIPTION_DEVICE_ME6100I4DIO "ME-6100I/4/DIO isolated device, 4 streaming analog outputs, 16 digital i/o lines."
305#define ME6000_DESCRIPTION_DEVICE_ME6100I8DIO "ME-6100I/8/DIO isolated device, 4 streaming, 4 single analog outputs, 16 digital i/o lines."
306#define ME6000_DESCRIPTION_DEVICE_ME6100I16DIO "ME-6100I/16/DIO isolated device, 4 streaming, 12 single analog outputs, 16 digital i/o lines."
307#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE4DIO "ME-6100ISLE/4/DIO isle device, 4 streaming analog outputs, 16 digital i/o lines."
308#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE8DIO "ME-6100ISLE/8/DIO isle device, 4 streaming, 4 single analog outputs, 16 digital i/o lines."
309#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE16DIO "ME-6100ISLE/16/DIO isle device, 4 streaming, 12 single analog outputs, 16 digital i/o lines."
310#define ME6000_DESCRIPTION_DEVICE_ME6200I9DIO "ME-6200I/9/DIO isolated device, 9 single analog outputs, 16 digital i/o lines."
311#define ME6000_DESCRIPTION_DEVICE_ME6300I9DIO "ME-6300I/9/DIO isolated device, 4 streaming, 5 single analog outputs, 16 digital i/o lines."
312
313/* ME-630 defines */
314#define ME0600_NAME_DRIVER "ME-0600"
315
316#define ME0600_NAME_DEVICE_ME0630 "ME-630"
317
318#define ME0600_DESCRIPTION_DEVICE_ME0630 "ME-630 device, up to 16 relay, 8 digital ttl input lines, 8 isolated digital input lines, 16 digital i/o lines, 2 external interrupts."
319
320/* ME-8100 defines */
321#define ME8100_NAME_DRIVER "ME-8100"
322
323#define ME8100_NAME_DEVICE_ME8100A "ME-8100A"
324#define ME8100_NAME_DEVICE_ME8100B "ME-8100B"
325
326#define ME8100_DESCRIPTION_DEVICE_ME8100A "ME-8100A opto isolated device, 16 digital input lines, 16 digital output lines."
327#define ME8100_DESCRIPTION_DEVICE_ME8100B "ME-8100B opto isolated device, 32 digital input lines, 32 digital output lines, 3 counters."
328
329/* ME-8200 defines */
330#define ME8200_NAME_DRIVER "ME-8200"
331
332#define ME8200_NAME_DEVICE_ME8200A "ME-8200A"
333#define ME8200_NAME_DEVICE_ME8200B "ME-8200B"
334
335#define ME8200_DESCRIPTION_DEVICE_ME8200A "ME-8200A opto isolated device, 8 digital output lines, 8 digital input lines, 16 digital i/o lines."
336#define ME8200_DESCRIPTION_DEVICE_ME8200B "ME-8200B opto isolated device, 16 digital output lines, 16 digital input lines, 16 digital i/o lines."
337
338/* ME-0900 defines */
339#define ME0900_NAME_DRIVER "ME-0900"
340
341#define ME0900_NAME_DEVICE_ME0940 "ME-94"
342#define ME0900_NAME_DEVICE_ME0950 "ME-95"
343#define ME0900_NAME_DEVICE_ME0960 "ME-96"
344
345#define ME0900_DESCRIPTION_DEVICE_ME0940 "ME-94 device, 16 digital input lines, 2 external interrupt lines."
346#define ME0900_DESCRIPTION_DEVICE_ME0950 "ME-95 device, 16 digital output lines."
347#define ME0900_DESCRIPTION_DEVICE_ME0960 "ME-96 device, 8 digital input lines, 8 digital output lines, 2 external interrupt lines."
348
349/* ME-DUMMY defines */
350#define MEDUMMY_NAME_DRIVER "ME-Dummy"
351
352/* MEPHISTO_S1 defines */
353/*
354#define MEPHISTO_S1_NAME_DRIVER "MEphisto Scope 1"
355#define MEPHISTO_S1_NAME_DEVICE "MEphisto Scope 1"
356#define MEPHISTO_S1_DESCRIPTION_DEVICE "MEphisto Scope 1 device, 2 analog inputs, 24 digital i/o."
357*/
358/* Error defines */
359#define EMPTY_NAME_DRIVER "ME-???"
360#define EMPTY_NAME_DEVICE "ME-???"
361#define EMPTY_DESCRIPTION_DEVICE "ME-??? unknown device"
362
363#endif
diff --git a/drivers/staging/meilhaus/meioctl.h b/drivers/staging/meilhaus/meioctl.h
new file mode 100644
index 000000000000..6dc719fba57c
--- /dev/null
+++ b/drivers/staging/meilhaus/meioctl.h
@@ -0,0 +1,515 @@
1/*
2 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File : meioctl.h
5 * Author : GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
6 */
7
8#ifndef _MEIOCTL_H_
9#define _MEIOCTL_H_
10
11
12/*=============================================================================
13 Types for the input/output ioctls
14 ===========================================================================*/
15
16typedef struct me_io_irq_start {
17 int device;
18 int subdevice;
19 int channel;
20 int irq_source;
21 int irq_edge;
22 int irq_arg;
23 int flags;
24 int errno;
25} me_io_irq_start_t;
26
27
28typedef struct me_io_irq_wait {
29 int device;
30 int subdevice;
31 int channel;
32 int irq_count;
33 int value;
34 int time_out;
35 int flags;
36 int errno;
37} me_io_irq_wait_t;
38
39
40typedef struct me_io_irq_stop {
41 int device;
42 int subdevice;
43 int channel;
44 int flags;
45 int errno;
46} me_io_irq_stop_t;
47
48
49typedef struct me_io_reset_device {
50 int device;
51 int flags;
52 int errno;
53} me_io_reset_device_t;
54
55
56typedef struct me_io_reset_subdevice {
57 int device;
58 int subdevice;
59 int flags;
60 int errno;
61} me_io_reset_subdevice_t;
62
63
64typedef struct me_io_single_config {
65 int device;
66 int subdevice;
67 int channel;
68 int single_config;
69 int ref;
70 int trig_chan;
71 int trig_type;
72 int trig_edge;
73 int flags;
74 int errno;
75} me_io_single_config_t;
76
77
78typedef struct me_io_single {
79 meIOSingle_t *single_list;
80 int count;
81 int flags;
82 int errno;
83} me_io_single_t;
84
85
86typedef struct me_io_stream_config {
87 int device;
88 int subdevice;
89 meIOStreamConfig_t *config_list;
90 int count;
91 meIOStreamTrigger_t trigger;
92 int fifo_irq_threshold;
93 int flags;
94 int errno;
95} me_io_stream_config_t;
96
97
98typedef struct me_io_stream_new_values {
99 int device;
100 int subdevice;
101 int time_out;
102 int count;
103 int flags;
104 int errno;
105} me_io_stream_new_values_t;
106
107
108typedef struct me_io_stream_read {
109 int device;
110 int subdevice;
111 int read_mode;
112 int *values;
113 int count;
114 int flags;
115 int errno;
116} me_io_stream_read_t;
117
118
119typedef struct me_io_stream_start {
120 meIOStreamStart_t *start_list;
121 int count;
122 int flags;
123 int errno;
124} me_io_stream_start_t;
125
126
127typedef struct me_io_stream_status {
128 int device;
129 int subdevice;
130 int wait;
131 int status;
132 int count;
133 int flags;
134 int errno;
135} me_io_stream_status_t;
136
137
138typedef struct me_io_stream_stop {
139 meIOStreamStop_t *stop_list;
140 int count;
141 int flags;
142 int errno;
143} me_io_stream_stop_t;
144
145
146typedef struct me_io_stream_write {
147 int device;
148 int subdevice;
149 int write_mode;
150 int *values;
151 int count;
152 int flags;
153 int errno;
154} me_io_stream_write_t;
155
156
157/*=============================================================================
158 Types for the lock ioctls
159 ===========================================================================*/
160
161typedef struct me_lock_device {
162 int device;
163 int lock;
164 int flags;
165 int errno;
166} me_lock_device_t;
167
168
169typedef struct me_lock_driver {
170 int flags;
171 int lock;
172 int errno;
173} me_lock_driver_t;
174
175
176typedef struct me_lock_subdevice {
177 int device;
178 int subdevice;
179 int lock;
180 int flags;
181 int errno;
182} me_lock_subdevice_t;
183
184
185/*=============================================================================
186 Types for the query ioctls
187 ===========================================================================*/
188
189typedef struct me_query_info_device {
190 int device;
191 int vendor_id;
192 int device_id;
193 int serial_no;
194 int bus_type;
195 int bus_no;
196 int dev_no;
197 int func_no;
198 int plugged;
199 int errno;
200} me_query_info_device_t;
201
202
203typedef struct me_query_description_device {
204 int device;
205 char *name;
206 int count;
207 int errno;
208} me_query_description_device_t;
209
210
211typedef struct me_query_name_device {
212 int device;
213 char *name;
214 int count;
215 int errno;
216} me_query_name_device_t;
217
218
219typedef struct me_query_name_device_driver {
220 int device;
221 char *name;
222 int count;
223 int errno;
224} me_query_name_device_driver_t;
225
226
227typedef struct me_query_version_main_driver {
228 int version;
229 int errno;
230} me_query_version_main_driver_t;
231
232
233typedef struct me_query_version_device_driver {
234 int device;
235 int version;
236 int errno;
237} me_query_version_device_driver_t;
238
239
240typedef struct me_query_number_devices {
241 int number;
242 int errno;
243} me_query_number_devices_t;
244
245
246typedef struct me_query_number_subdevices {
247 int device;
248 int number;
249 int errno;
250} me_query_number_subdevices_t;
251
252
253typedef struct me_query_number_channels {
254 int device;
255 int subdevice;
256 int number;
257 int errno;
258} me_query_number_channels_t;
259
260
261typedef struct me_query_number_ranges {
262 int device;
263 int subdevice;
264 int channel;
265 int unit;
266 int number;
267 int errno;
268} me_query_number_ranges_t;
269
270
271typedef struct me_query_subdevice_by_type {
272 int device;
273 int start_subdevice;
274 int type;
275 int subtype;
276 int subdevice;
277 int errno;
278} me_query_subdevice_by_type_t;
279
280
281typedef struct me_query_subdevice_type {
282 int device;
283 int subdevice;
284 int type;
285 int subtype;
286 int errno;
287} me_query_subdevice_type_t;
288
289
290typedef struct me_query_subdevice_caps {
291 int device;
292 int subdevice;
293 int caps;
294 int errno;
295} me_query_subdevice_caps_t;
296
297
298typedef struct me_query_subdevice_caps_args {
299 int device;
300 int subdevice;
301 int cap;
302 int args[8];
303 int count;
304 int errno;
305} me_query_subdevice_caps_args_t;
306
307
308typedef struct me_query_timer {
309 int device;
310 int subdevice;
311 int timer;
312 int base_frequency;
313 long long min_ticks;
314 long long max_ticks;
315 int errno;
316} me_query_timer_t;
317
318
319typedef struct me_query_range_by_min_max {
320 int device;
321 int subdevice;
322 int channel;
323 int unit;
324 int min;
325 int max;
326 int max_data;
327 int range;
328 int errno;
329} me_query_range_by_min_max_t;
330
331
332typedef struct me_query_range_info {
333 int device;
334 int subdevice;
335 int channel;
336 int unit;
337 int range;
338 int min;
339 int max;
340 int max_data;
341 int errno;
342} me_query_range_info_t;
343
344
345/*=============================================================================
346 Types for the configuration ioctls
347 ===========================================================================*/
348
349typedef struct me_cfg_tcpip_location {
350 int access_type;
351 char *remote_host;
352 int remote_device_number;
353} me_cfg_tcpip_location_t;
354
355
356typedef union me_cfg_tcpip {
357 int access_type;
358 me_cfg_tcpip_location_t location;
359} me_cfg_tcpip_t;
360
361
362typedef struct me_cfg_pci_hw_location {
363 unsigned int bus_type;
364 unsigned int bus_no;
365 unsigned int device_no;
366 unsigned int function_no;
367} me_cfg_pci_hw_location_t;
368
369/*
370typedef struct me_cfg_usb_hw_location {
371 unsigned int bus_type;
372 unsigned int root_hub_no;
373} me_cfg_usb_hw_location_t;
374*/
375
376typedef union me_cfg_hw_location {
377 unsigned int bus_type;
378 me_cfg_pci_hw_location_t pci;
379// me_cfg_usb_hw_location_t usb;
380} me_cfg_hw_location_t;
381
382
383typedef struct me_cfg_device_info {
384 unsigned int vendor_id;
385 unsigned int device_id;
386 unsigned int serial_no;
387 me_cfg_hw_location_t hw_location;
388} me_cfg_device_info_t;
389
390
391typedef struct me_cfg_subdevice_info {
392 int type;
393 int sub_type;
394 unsigned int number_channels;
395} me_cfg_subdevice_info_t;
396
397
398typedef struct me_cfg_range_entry {
399 int unit;
400 double min;
401 double max;
402 unsigned int max_data;
403} me_cfg_range_entry_t;
404
405
406typedef struct me_cfg_mux32m_device {
407 int type;
408 int timed;
409 unsigned int ai_channel;
410 unsigned int dio_device;
411 unsigned int dio_subdevice;
412 unsigned int timer_device;
413 unsigned int timer_subdevice;
414 unsigned int mux32s_count;
415} me_cfg_mux32m_device_t;
416
417
418typedef struct me_cfg_demux32_device {
419 int type;
420 int timed;
421 unsigned int ao_channel;
422 unsigned int dio_device;
423 unsigned int dio_subdevice;
424 unsigned int timer_device;
425 unsigned int timer_subdevice;
426} me_cfg_demux32_device_t;
427
428
429typedef union me_cfg_external_device {
430 int type;
431 me_cfg_mux32m_device_t mux32m;
432 me_cfg_demux32_device_t demux32;
433} me_cfg_external_device_t;
434
435
436typedef struct me_cfg_subdevice_entry {
437 me_cfg_subdevice_info_t info;
438 me_cfg_range_entry_t *range_list;
439 unsigned int count;
440 int locked;
441 me_cfg_external_device_t external_device;
442} me_cfg_subdevice_entry_t;
443
444
445typedef struct me_cfg_device_entry {
446 me_cfg_tcpip_t tcpip;
447 me_cfg_device_info_t info;
448 me_cfg_subdevice_entry_t *subdevice_list;
449 unsigned int count;
450} me_cfg_device_entry_t;
451
452
453typedef struct me_config_load {
454 me_cfg_device_entry_t *device_list;
455 unsigned int count;
456 int errno;
457} me_config_load_t;
458
459
460/*=============================================================================
461 The ioctls of the board
462 ===========================================================================*/
463
464#define MEMAIN_MAGIC 'y'
465
466#define ME_IO_IRQ_ENABLE _IOR (MEMAIN_MAGIC, 1, me_io_irq_start_t)
467#define ME_IO_IRQ_WAIT _IOR (MEMAIN_MAGIC, 2, me_io_irq_wait_t)
468#define ME_IO_IRQ_DISABLE _IOR (MEMAIN_MAGIC, 3, me_io_irq_stop_t)
469
470#define ME_IO_RESET_DEVICE _IOW (MEMAIN_MAGIC, 4, me_io_reset_device_t)
471#define ME_IO_RESET_SUBDEVICE _IOW (MEMAIN_MAGIC, 5, me_io_reset_subdevice_t)
472
473#define ME_IO_SINGLE _IOWR(MEMAIN_MAGIC, 6, me_io_single_t)
474#define ME_IO_SINGLE_CONFIG _IOW (MEMAIN_MAGIC, 7, me_io_single_config_t)
475
476#define ME_IO_STREAM_CONFIG _IOW (MEMAIN_MAGIC, 8, me_io_stream_config_t)
477#define ME_IO_STREAM_NEW_VALUES _IOR (MEMAIN_MAGIC, 9, me_io_stream_new_values_t)
478#define ME_IO_STREAM_READ _IOR (MEMAIN_MAGIC, 10, me_io_stream_read_t)
479#define ME_IO_STREAM_START _IOW (MEMAIN_MAGIC, 11, me_io_stream_start_t)
480#define ME_IO_STREAM_STATUS _IOR (MEMAIN_MAGIC, 12, me_io_stream_status_t)
481#define ME_IO_STREAM_STOP _IOW (MEMAIN_MAGIC, 13, me_io_stream_stop_t)
482#define ME_IO_STREAM_WRITE _IOW (MEMAIN_MAGIC, 14, me_io_stream_write_t)
483
484#define ME_LOCK_DRIVER _IOW (MEMAIN_MAGIC, 15, me_lock_driver_t)
485#define ME_LOCK_DEVICE _IOW (MEMAIN_MAGIC, 16, me_lock_device_t)
486#define ME_LOCK_SUBDEVICE _IOW (MEMAIN_MAGIC, 17, me_lock_subdevice_t)
487
488#define ME_QUERY_DESCRIPTION_DEVICE _IOR (MEMAIN_MAGIC, 18, me_query_description_device_t)
489
490#define ME_QUERY_INFO_DEVICE _IOR (MEMAIN_MAGIC, 19, me_query_info_device_t)
491
492#define ME_QUERY_NAME_DEVICE _IOR (MEMAIN_MAGIC, 20, me_query_name_device_t)
493#define ME_QUERY_NAME_DEVICE_DRIVER _IOR (MEMAIN_MAGIC, 21, me_query_name_device_driver_t)
494
495#define ME_QUERY_NUMBER_DEVICES _IOR (MEMAIN_MAGIC, 22, me_query_number_devices_t)
496#define ME_QUERY_NUMBER_SUBDEVICES _IOR (MEMAIN_MAGIC, 23, me_query_number_subdevices_t)
497#define ME_QUERY_NUMBER_CHANNELS _IOR (MEMAIN_MAGIC, 24, me_query_number_channels_t)
498#define ME_QUERY_NUMBER_RANGES _IOR (MEMAIN_MAGIC, 25, me_query_number_ranges_t)
499
500#define ME_QUERY_RANGE_BY_MIN_MAX _IOR (MEMAIN_MAGIC, 26, me_query_range_by_min_max_t)
501#define ME_QUERY_RANGE_INFO _IOR (MEMAIN_MAGIC, 27, me_query_range_info_t)
502
503#define ME_QUERY_SUBDEVICE_BY_TYPE _IOR (MEMAIN_MAGIC, 28, me_query_subdevice_by_type_t)
504#define ME_QUERY_SUBDEVICE_TYPE _IOR (MEMAIN_MAGIC, 29, me_query_subdevice_type_t)
505#define ME_QUERY_SUBDEVICE_CAPS _IOR (MEMAIN_MAGIC, 29, me_query_subdevice_caps_t)
506#define ME_QUERY_SUBDEVICE_CAPS_ARGS _IOR (MEMAIN_MAGIC, 30, me_query_subdevice_caps_args_t)
507
508#define ME_QUERY_TIMER _IOR (MEMAIN_MAGIC, 31, me_query_timer_t)
509
510#define ME_QUERY_VERSION_DEVICE_DRIVER _IOR (MEMAIN_MAGIC, 32, me_query_version_device_driver_t)
511#define ME_QUERY_VERSION_MAIN_DRIVER _IOR (MEMAIN_MAGIC, 33, me_query_version_main_driver_t)
512
513#define ME_CONFIG_LOAD _IOWR(MEMAIN_MAGIC, 34, me_config_load_t)
514
515#endif
diff --git a/drivers/staging/meilhaus/memain.c b/drivers/staging/meilhaus/memain.c
new file mode 100644
index 000000000000..6cdeb8582453
--- /dev/null
+++ b/drivers/staging/meilhaus/memain.c
@@ -0,0 +1,2022 @@
1/**
2 * @file memain.c
3 *
4 * @brief Main Meilhaus device driver.
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#ifndef MODULE
33# define MODULE
34#endif
35
36#include <linux/module.h>
37#include <linux/pci.h>
38//#include <linux/usb.h>
39#include <linux/errno.h>
40#include <asm/uaccess.h>
41#include <linux/cdev.h>
42#include <linux/rwsem.h>
43
44#include "medefines.h"
45#include "metypes.h"
46#include "meerror.h"
47
48#include "medebug.h"
49#include "memain.h"
50#include "medevice.h"
51#include "meioctl.h"
52#include "mecommon.h"
53
54/* Module parameters
55*/
56
57#ifdef BOSCH
58static unsigned int me_bosch_fw = 0;
59
60# ifdef module_param
61module_param(me_bosch_fw, int, S_IRUGO);
62# else
63MODULE_PARM(me_bosch_fw, "i");
64# endif
65
66MODULE_PARM_DESC(me_bosch_fw,
67 "Flags which signals the ME-4600 driver to load the bosch firmware (default = 0).");
68#endif //BOSCH
69
70static unsigned int major = 0;
71#ifdef module_param
72module_param(major, int, S_IRUGO);
73#else
74MODULE_PARM(major, "i");
75#endif
76
77/* Global Driver Lock
78*/
79
80static struct file *me_filep = NULL;
81static int me_count = 0;
82static spinlock_t me_lock = SPIN_LOCK_UNLOCKED;
83static DECLARE_RWSEM(me_rwsem);
84
85/* Board instances are kept in a global list */
86LIST_HEAD(me_device_list);
87
88/* Prototypes
89*/
90
91static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id);
92static void me_remove_pci(struct pci_dev *dev);
93static int insert_to_device_list(me_device_t * n_device);
94static int replace_with_dummy(int vendor_id, int device_id, int serial_no);
95static void clear_device_list(void);
96static int me_open(struct inode *inode_ptr, struct file *filep);
97static int me_release(struct inode *, struct file *);
98static int me_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
99//static int me_probe_usb(struct usb_interface *interface, const struct usb_device_id *id);
100//static void me_disconnect_usb(struct usb_interface *interface);
101
102/* Character device structure
103*/
104
105static struct cdev *cdevp;
106
107/* File operations provided by the module
108*/
109
110static struct file_operations me_file_operations = {
111 .owner = THIS_MODULE,
112 .ioctl = me_ioctl,
113 .open = me_open,
114 .release = me_release,
115};
116
117struct pci_driver me_pci_driver = {
118 .name = MEMAIN_NAME,
119 .id_table = me_pci_table,
120 .probe = me_probe_pci,
121 .remove = me_remove_pci
122};
123
124/* //me_usb_driver
125static struct usb_driver me_usb_driver =
126{
127 .name = MEMAIN_NAME,
128 .id_table = me_usb_table,
129 .probe = me_probe_usb,
130 .disconnect = me_disconnect_usb
131};
132*/
133
134#ifdef ME_LOCK_MULTIPLEX_TEMPLATE
135ME_LOCK_MULTIPLEX_TEMPLATE("me_lock_device",
136 me_lock_device_t,
137 me_lock_device,
138 me_device_lock_device,
139 (device, filep, karg.lock, karg.flags))
140
141 ME_LOCK_MULTIPLEX_TEMPLATE("me_lock_subdevice",
142 me_lock_subdevice_t,
143 me_lock_subdevice,
144 me_device_lock_subdevice,
145 (device, filep, karg.subdevice, karg.lock,
146 karg.flags))
147#else
148#error macro ME_LOCK_MULTIPLEX_TEMPLATE not defined
149#endif
150
151#ifdef ME_IO_MULTIPLEX_TEMPLATE
152ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_start",
153 me_io_irq_start_t,
154 me_io_irq_start,
155 me_device_io_irq_start,
156 (device,
157 filep,
158 karg.subdevice,
159 karg.channel,
160 karg.irq_source,
161 karg.irq_edge, karg.irq_arg, karg.flags))
162
163 ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_wait",
164 me_io_irq_wait_t,
165 me_io_irq_wait,
166 me_device_io_irq_wait,
167 (device,
168 filep,
169 karg.subdevice,
170 karg.channel,
171 &karg.irq_count, &karg.value, karg.time_out, karg.flags))
172
173 ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_stop",
174 me_io_irq_stop_t,
175 me_io_irq_stop,
176 me_device_io_irq_stop,
177 (device,
178 filep, karg.subdevice, karg.channel, karg.flags))
179
180 ME_IO_MULTIPLEX_TEMPLATE("me_io_reset_device",
181 me_io_reset_device_t,
182 me_io_reset_device,
183 me_device_io_reset_device, (device, filep, karg.flags))
184
185 ME_IO_MULTIPLEX_TEMPLATE("me_io_reset_subdevice",
186 me_io_reset_subdevice_t,
187 me_io_reset_subdevice,
188 me_device_io_reset_subdevice,
189 (device, filep, karg.subdevice, karg.flags))
190
191 ME_IO_MULTIPLEX_TEMPLATE("me_io_single_config",
192 me_io_single_config_t,
193 me_io_single_config,
194 me_device_io_single_config,
195 (device,
196 filep,
197 karg.subdevice,
198 karg.channel,
199 karg.single_config,
200 karg.ref,
201 karg.trig_chan,
202 karg.trig_type, karg.trig_edge, karg.flags))
203
204 ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_new_values",
205 me_io_stream_new_values_t,
206 me_io_stream_new_values,
207 me_device_io_stream_new_values,
208 (device,
209 filep,
210 karg.subdevice, karg.time_out, &karg.count, karg.flags))
211
212 ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_read",
213 me_io_stream_read_t,
214 me_io_stream_read,
215 me_device_io_stream_read,
216 (device,
217 filep,
218 karg.subdevice,
219 karg.read_mode, karg.values, &karg.count, karg.flags))
220
221 ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_status",
222 me_io_stream_status_t,
223 me_io_stream_status,
224 me_device_io_stream_status,
225 (device,
226 filep,
227 karg.subdevice,
228 karg.wait, &karg.status, &karg.count, karg.flags))
229
230 ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_write",
231 me_io_stream_write_t,
232 me_io_stream_write,
233 me_device_io_stream_write,
234 (device,
235 filep,
236 karg.subdevice,
237 karg.write_mode, karg.values, &karg.count, karg.flags))
238#else
239#error macro ME_IO_MULTIPLEX_TEMPLATE not defined
240#endif
241
242#ifdef ME_QUERY_MULTIPLEX_STR_TEMPLATE
243ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_name_device",
244 me_query_name_device_t,
245 me_query_name_device,
246 me_device_query_name_device, (device, &msg))
247
248 ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_name_device_driver",
249 me_query_name_device_driver_t,
250 me_query_name_device_driver,
251 me_device_query_name_device_driver,
252 (device, &msg))
253
254 ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_description_device",
255 me_query_description_device_t,
256 me_query_description_device,
257 me_device_query_description_device,
258 (device, &msg))
259#else
260#error macro ME_QUERY_MULTIPLEX_STR_TEMPLATE not defined
261#endif
262
263#ifdef ME_QUERY_MULTIPLEX_TEMPLATE
264ME_QUERY_MULTIPLEX_TEMPLATE("me_query_info_device",
265 me_query_info_device_t,
266 me_query_info_device,
267 me_device_query_info_device,
268 (device,
269 &karg.vendor_id,
270 &karg.device_id,
271 &karg.serial_no,
272 &karg.bus_type,
273 &karg.bus_no,
274 &karg.dev_no, &karg.func_no, &karg.plugged))
275
276 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_subdevices",
277 me_query_number_subdevices_t,
278 me_query_number_subdevices,
279 me_device_query_number_subdevices,
280 (device, &karg.number))
281
282 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_channels",
283 me_query_number_channels_t,
284 me_query_number_channels,
285 me_device_query_number_channels,
286 (device, karg.subdevice, &karg.number))
287
288 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_by_type",
289 me_query_subdevice_by_type_t,
290 me_query_subdevice_by_type,
291 me_device_query_subdevice_by_type,
292 (device,
293 karg.start_subdevice,
294 karg.type, karg.subtype, &karg.subdevice))
295
296 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_type",
297 me_query_subdevice_type_t,
298 me_query_subdevice_type,
299 me_device_query_subdevice_type,
300 (device, karg.subdevice, &karg.type, &karg.subtype))
301
302 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_caps",
303 me_query_subdevice_caps_t,
304 me_query_subdevice_caps,
305 me_device_query_subdevice_caps,
306 (device, karg.subdevice, &karg.caps))
307
308 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_caps_args",
309 me_query_subdevice_caps_args_t,
310 me_query_subdevice_caps_args,
311 me_device_query_subdevice_caps_args,
312 (device, karg.subdevice, karg.cap, karg.args,
313 karg.count))
314
315 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_ranges",
316 me_query_number_ranges_t,
317 me_query_number_ranges,
318 me_device_query_number_ranges,
319 (device, karg.subdevice, karg.unit, &karg.number))
320
321 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_range_by_min_max",
322 me_query_range_by_min_max_t,
323 me_query_range_by_min_max,
324 me_device_query_range_by_min_max,
325 (device,
326 karg.subdevice,
327 karg.unit,
328 &karg.min, &karg.max, &karg.max_data, &karg.range))
329
330 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_range_info",
331 me_query_range_info_t,
332 me_query_range_info,
333 me_device_query_range_info,
334 (device,
335 karg.subdevice,
336 karg.range,
337 &karg.unit, &karg.min, &karg.max, &karg.max_data))
338
339 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_timer",
340 me_query_timer_t,
341 me_query_timer,
342 me_device_query_timer,
343 (device,
344 karg.subdevice,
345 karg.timer,
346 &karg.base_frequency,
347 &karg.min_ticks, &karg.max_ticks))
348
349 ME_QUERY_MULTIPLEX_TEMPLATE("me_query_version_device_driver",
350 me_query_version_device_driver_t,
351 me_query_version_device_driver,
352 me_device_query_version_device_driver,
353 (device, &karg.version))
354#else
355#error macro ME_QUERY_MULTIPLEX_TEMPLATE not defined
356#endif
357
358/** ******************************************************************************** **/
359
360static me_device_t *get_dummy_instance(unsigned short vendor_id,
361 unsigned short device_id,
362 unsigned int serial_no,
363 int bus_type,
364 int bus_no, int dev_no, int func_no)
365{
366 int err;
367 me_dummy_constructor_t constructor = NULL;
368 me_device_t *instance;
369
370 PDEBUG("executed.\n");
371
372 if ((constructor = symbol_get(medummy_constructor)) == NULL) {
373 err = request_module(MEDUMMY_NAME);
374
375 if (err) {
376 PERROR("Error while request for module %s.\n",
377 MEDUMMY_NAME);
378 return NULL;
379 }
380
381 if ((constructor = symbol_get(medummy_constructor)) == NULL) {
382 PERROR("Can't get %s driver module constructor.\n",
383 MEDUMMY_NAME);
384 return NULL;
385 }
386 }
387
388 if ((instance = (*constructor) (vendor_id,
389 device_id,
390 serial_no,
391 bus_type,
392 bus_no, dev_no, func_no)) == NULL)
393 symbol_put(medummy_constructor);
394
395 return instance;
396}
397
398static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id)
399{
400 int err;
401 me_pci_constructor_t constructor = NULL;
402#ifdef BOSCH
403 me_bosch_constructor_t constructor_bosch = NULL;
404#endif
405 me_device_t *n_device = NULL;
406 uint32_t device;
407
408 char constructor_name[24] = "me0000_pci_constructor";
409 char module_name[7] = "me0000";
410
411 PDEBUG("executed.\n");
412 device = dev->device;
413 if ((device & 0xF000) == 0x6000) { // Exceptions: me61xx, me62xx, me63xx are handled by one driver.
414 device &= 0xF0FF;
415 }
416
417 constructor_name[2] += (char)((device >> 12) & 0x000F);
418 constructor_name[3] += (char)((device >> 8) & 0x000F);
419 PDEBUG("constructor_name: %s\n", constructor_name);
420 module_name[2] += (char)((device >> 12) & 0x000F);
421 module_name[3] += (char)((device >> 8) & 0x000F);
422 PDEBUG("module_name: %s\n", module_name);
423
424 if ((constructor =
425 (me_pci_constructor_t) __symbol_get(constructor_name)) == NULL) {
426 if (request_module(module_name)) {
427 PERROR("Error while request for module %s.\n",
428 module_name);
429 return -ENODEV;
430 }
431
432 if ((constructor =
433 (me_pci_constructor_t) __symbol_get(constructor_name)) ==
434 NULL) {
435 PERROR("Can't get %s driver module constructor.\n",
436 module_name);
437 return -ENODEV;
438 }
439 }
440#ifdef BOSCH
441 if ((device & 0xF000) == 0x4000) { // Bosch build has differnt constructor for me4600.
442 if ((n_device =
443 (*constructor_bosch) (dev, me_bosch_fw)) == NULL) {
444 __symbol_put(constructor_name);
445 PERROR
446 ("Can't get device instance of %s driver module.\n",
447 module_name);
448 return -ENODEV;
449 }
450 } else {
451#endif
452 if ((n_device = (*constructor) (dev)) == NULL) {
453 __symbol_put(constructor_name);
454 PERROR
455 ("Can't get device instance of %s driver module.\n",
456 module_name);
457 return -ENODEV;
458 }
459#ifdef BOSCH
460 }
461#endif
462
463 insert_to_device_list(n_device);
464 err =
465 n_device->me_device_io_reset_device(n_device, NULL,
466 ME_IO_RESET_DEVICE_NO_FLAGS);
467 if (err) {
468 PERROR("Error while reseting device.\n");
469 } else {
470 PDEBUG("Reseting device was sucessful.\n");
471 }
472 return ME_ERRNO_SUCCESS;
473}
474
475static void release_instance(me_device_t * device)
476{
477 int vendor_id;
478 int device_id;
479 int serial_no;
480 int bus_type;
481 int bus_no;
482 int dev_no;
483 int func_no;
484 int plugged;
485
486 uint32_t dev_id;
487
488 char constructor_name[24] = "me0000_pci_constructor";
489
490 PDEBUG("executed.\n");
491
492 device->me_device_query_info_device(device,
493 &vendor_id,
494 &device_id,
495 &serial_no,
496 &bus_type,
497 &bus_no,
498 &dev_no, &func_no, &plugged);
499
500 dev_id = device_id;
501 device->me_device_destructor(device);
502
503 if (plugged != ME_PLUGGED_IN) {
504 PDEBUG("release: medummy_constructor\n");
505
506 __symbol_put("medummy_constructor");
507 } else {
508 if ((dev_id & 0xF000) == 0x6000) { // Exceptions: me61xx, me62xx, me63xx are handled by one driver.
509 dev_id &= 0xF0FF;
510 }
511
512 constructor_name[2] += (char)((dev_id >> 12) & 0x000F);
513 constructor_name[3] += (char)((dev_id >> 8) & 0x000F);
514 PDEBUG("release: %s\n", constructor_name);
515
516 __symbol_put(constructor_name);
517 }
518}
519
520static int insert_to_device_list(me_device_t * n_device)
521{
522 me_device_t *o_device = NULL;
523
524 struct list_head *pos;
525 int n_vendor_id;
526 int n_device_id;
527 int n_serial_no;
528 int n_bus_type;
529 int n_bus_no;
530 int n_dev_no;
531 int n_func_no;
532 int n_plugged;
533 int o_vendor_id;
534 int o_device_id;
535 int o_serial_no;
536 int o_bus_type;
537 int o_bus_no;
538 int o_dev_no;
539 int o_func_no;
540 int o_plugged;
541
542 PDEBUG("executed.\n");
543
544 n_device->me_device_query_info_device(n_device,
545 &n_vendor_id,
546 &n_device_id,
547 &n_serial_no,
548 &n_bus_type,
549 &n_bus_no,
550 &n_dev_no,
551 &n_func_no, &n_plugged);
552
553 down_write(&me_rwsem);
554
555 list_for_each(pos, &me_device_list) {
556 o_device = list_entry(pos, me_device_t, list);
557 o_device->me_device_query_info_device(o_device,
558 &o_vendor_id,
559 &o_device_id,
560 &o_serial_no,
561 &o_bus_type,
562 &o_bus_no,
563 &o_dev_no,
564 &o_func_no, &o_plugged);
565
566 if (o_plugged == ME_PLUGGED_OUT) {
567 if (((o_vendor_id == n_vendor_id) &&
568 (o_device_id == n_device_id) &&
569 (o_serial_no == n_serial_no) &&
570 (o_bus_type == n_bus_type)) ||
571 ((o_vendor_id == n_vendor_id) &&
572 (o_device_id == n_device_id) &&
573 (o_bus_type == n_bus_type) &&
574 (o_bus_no == n_bus_no) &&
575 (o_dev_no == n_dev_no) &&
576 (o_func_no == n_func_no))) {
577 n_device->list.prev = pos->prev;
578 n_device->list.next = pos->next;
579 pos->prev->next = &n_device->list;
580 pos->next->prev = &n_device->list;
581 release_instance(o_device);
582 break;
583 }
584 }
585 }
586
587 if (pos == &me_device_list) {
588 list_add_tail(&n_device->list, &me_device_list);
589 }
590
591 up_write(&me_rwsem);
592
593 return 0;
594}
595
596static void me_remove_pci(struct pci_dev *dev)
597{
598 int vendor_id = dev->vendor;
599 int device_id = dev->device;
600 int subsystem_vendor = dev->subsystem_vendor;
601 int subsystem_device = dev->subsystem_device;
602 int serial_no = (subsystem_device << 16) | subsystem_vendor;
603
604 PDEBUG("executed.\n");
605
606 PINFO("Vendor id = 0x%08X\n", vendor_id);
607 PINFO("Device id = 0x%08X\n", device_id);
608 PINFO("Serial Number = 0x%08X\n", serial_no);
609
610 replace_with_dummy(vendor_id, device_id, serial_no);
611}
612
613static int replace_with_dummy(int vendor_id, int device_id, int serial_no)
614{
615
616 struct list_head *pos;
617 me_device_t *n_device = NULL;
618 me_device_t *o_device = NULL;
619 int o_vendor_id;
620 int o_device_id;
621 int o_serial_no;
622 int o_bus_type;
623 int o_bus_no;
624 int o_dev_no;
625 int o_func_no;
626 int o_plugged;
627
628 PDEBUG("executed.\n");
629
630 down_write(&me_rwsem);
631
632 list_for_each(pos, &me_device_list) {
633 o_device = list_entry(pos, me_device_t, list);
634 o_device->me_device_query_info_device(o_device,
635 &o_vendor_id,
636 &o_device_id,
637 &o_serial_no,
638 &o_bus_type,
639 &o_bus_no,
640 &o_dev_no,
641 &o_func_no, &o_plugged);
642
643 if (o_plugged == ME_PLUGGED_IN) {
644 if (((o_vendor_id == vendor_id) &&
645 (o_device_id == device_id) &&
646 (o_serial_no == serial_no))) {
647 n_device = get_dummy_instance(o_vendor_id,
648 o_device_id,
649 o_serial_no,
650 o_bus_type,
651 o_bus_no,
652 o_dev_no,
653 o_func_no);
654
655 if (!n_device) {
656 up_write(&me_rwsem);
657 PERROR("Cannot get dummy instance.\n");
658 return 1;
659 }
660
661 n_device->list.prev = pos->prev;
662
663 n_device->list.next = pos->next;
664 pos->prev->next = &n_device->list;
665 pos->next->prev = &n_device->list;
666 release_instance(o_device);
667 break;
668 }
669 }
670 }
671
672 up_write(&me_rwsem);
673
674 return 0;
675}
676
677static void clear_device_list(void)
678{
679
680 struct list_head *entry;
681 me_device_t *device;
682
683 // Clear the device info list .
684 down_write(&me_rwsem);
685
686 while (!list_empty(&me_device_list)) {
687 entry = me_device_list.next;
688 device = list_entry(entry, me_device_t, list);
689 list_del(entry);
690 release_instance(device);
691 }
692
693 up_write(&me_rwsem);
694}
695
696static int lock_driver(struct file *filep, int lock, int flags)
697{
698 int err = ME_ERRNO_SUCCESS;
699 me_device_t *device;
700
701 PDEBUG("executed.\n");
702
703 down_read(&me_rwsem);
704
705 spin_lock(&me_lock);
706
707 switch (lock) {
708
709 case ME_LOCK_SET:
710 if (me_count) {
711 PERROR
712 ("Driver System is currently used by another process.\n");
713 err = ME_ERRNO_USED;
714 } else if ((me_filep != NULL) && (me_filep != filep)) {
715 PERROR
716 ("Driver System is already logged by another process.\n");
717 err = ME_ERRNO_LOCKED;
718 } else {
719 list_for_each_entry(device, &me_device_list, list) {
720 err =
721 device->me_device_lock_device(device, filep,
722 ME_LOCK_CHECK,
723 flags);
724
725 if (err)
726 break;
727 }
728
729 if (!err)
730 me_filep = filep;
731 }
732
733 break;
734
735 case ME_LOCK_RELEASE:
736 if ((me_filep != NULL) && (me_filep != filep)) {
737 err = ME_ERRNO_SUCCESS;
738 } else {
739 list_for_each_entry(device, &me_device_list, list) {
740 device->me_device_lock_device(device, filep,
741 ME_LOCK_RELEASE,
742 flags);
743 }
744
745 me_filep = NULL;
746 }
747
748 break;
749
750 default:
751 PERROR("Invalid lock specified.\n");
752
753 err = ME_ERRNO_INVALID_LOCK;
754
755 break;
756 }
757
758 spin_unlock(&me_lock);
759
760 up_read(&me_rwsem);
761
762 return err;
763}
764
765static int me_lock_driver(struct file *filep, me_lock_driver_t * arg)
766{
767 int err = 0;
768
769 me_lock_driver_t lock;
770
771 PDEBUG("executed.\n");
772
773 err = copy_from_user(&lock, arg, sizeof(me_lock_driver_t));
774
775 if (err) {
776 PERROR("Can't copy arguments to kernel space.\n");
777 return -EFAULT;
778 }
779
780 lock.errno = lock_driver(filep, lock.lock, lock.flags);
781
782 err = copy_to_user(arg, &lock, sizeof(me_lock_driver_t));
783
784 if (err) {
785 PERROR("Can't copy query back to user space.\n");
786 return -EFAULT;
787 }
788
789 return ME_ERRNO_SUCCESS;
790}
791
792static int me_open(struct inode *inode_ptr, struct file *filep)
793{
794
795 PDEBUG("executed.\n");
796 // Nothing to do here.
797 return 0;
798}
799
800static int me_release(struct inode *inode_ptr, struct file *filep)
801{
802
803 PDEBUG("executed.\n");
804 lock_driver(filep, ME_LOCK_RELEASE, ME_LOCK_DRIVER_NO_FLAGS);
805
806 return 0;
807}
808
809static int me_query_version_main_driver(struct file *filep,
810 me_query_version_main_driver_t * arg)
811{
812 int err;
813 me_query_version_main_driver_t karg;
814
815 PDEBUG("executed.\n");
816
817 karg.version = ME_VERSION_DRIVER;
818 karg.errno = ME_ERRNO_SUCCESS;
819
820 err = copy_to_user(arg, &karg, sizeof(me_query_version_main_driver_t));
821
822 if (err) {
823 PERROR("Can't copy query back to user space.\n");
824 return -EFAULT;
825 }
826
827 return 0;
828}
829
830static int me_config_load_device(struct file *filep,
831 me_cfg_device_entry_t * karg, int device_no)
832{
833
834 int err = ME_ERRNO_SUCCESS;
835 int k = 0;
836
837 struct list_head *pos = NULL;
838 me_device_t *device = NULL;
839
840 PDEBUG("executed.\n");
841
842 list_for_each(pos, &me_device_list) {
843 if (k == device_no) {
844 device = list_entry(pos, me_device_t, list);
845 break;
846 }
847
848 k++;
849 }
850
851 if (pos == &me_device_list) {
852 PERROR("Invalid device number specified.\n");
853 return ME_ERRNO_INVALID_DEVICE;
854 } else {
855 spin_lock(&me_lock);
856
857 if ((me_filep != NULL) && (me_filep != filep)) {
858 spin_unlock(&me_lock);
859 PERROR("Resource is locked by another process.\n");
860 return ME_ERRNO_LOCKED;
861 } else {
862 me_count++;
863 spin_unlock(&me_lock);
864
865 err =
866 device->me_device_config_load(device, filep, karg);
867
868 spin_lock(&me_lock);
869 me_count--;
870 spin_unlock(&me_lock);
871 }
872 }
873
874 return err;
875}
876
877static int me_config_load(struct file *filep, me_config_load_t * arg)
878{
879 int err;
880 int i;
881 me_config_load_t cfg_setup;
882 me_config_load_t karg_cfg_setup;
883
884 struct list_head *pos = NULL;
885
886 struct list_head new_list;
887 me_device_t *o_device;
888 me_device_t *n_device;
889 int o_vendor_id;
890 int o_device_id;
891 int o_serial_no;
892 int o_bus_type;
893 int o_bus_no;
894 int o_dev_no;
895 int o_func_no;
896 int o_plugged;
897
898 PDEBUG("executed.\n");
899
900 // Copy argument to kernel space.
901 err = copy_from_user(&karg_cfg_setup, arg, sizeof(me_config_load_t));
902
903 if (err) {
904 PERROR("Can't copy arguments to kernel space.\n");
905 return -EFAULT;
906 }
907 // Allocate kernel buffer for device list.
908 cfg_setup.device_list =
909 kmalloc(sizeof(me_cfg_device_entry_t) * karg_cfg_setup.count,
910 GFP_KERNEL);
911
912 if (!cfg_setup.device_list) {
913 PERROR("Can't get buffer %li for device list.\n",
914 sizeof(me_cfg_device_entry_t) * karg_cfg_setup.count);
915 return -ENOMEM;
916 }
917 // Copy device list to kernel space.
918 err =
919 copy_from_user(cfg_setup.device_list, karg_cfg_setup.device_list,
920 sizeof(me_cfg_device_entry_t) *
921 karg_cfg_setup.count);
922
923 if (err) {
924 PERROR("Can't copy device list to kernel space.\n");
925 kfree(cfg_setup.device_list);
926 return -EFAULT;
927 }
928
929 cfg_setup.count = karg_cfg_setup.count;
930
931 INIT_LIST_HEAD(&new_list);
932
933 down_write(&me_rwsem);
934
935 spin_lock(&me_lock);
936
937 if ((me_filep != NULL) && (me_filep != filep)) {
938 spin_unlock(&me_lock);
939 PERROR("Driver System is logged by another process.\n");
940 karg_cfg_setup.errno = ME_ERRNO_LOCKED;
941 } else {
942 me_count++;
943 spin_unlock(&me_lock);
944
945 for (i = 0; i < karg_cfg_setup.count; i++) {
946 PDEBUG("me_config_load() device=%d.\n", i);
947 if (cfg_setup.device_list[i].tcpip.access_type ==
948 ME_ACCESS_TYPE_LOCAL) {
949 list_for_each(pos, &me_device_list) {
950 o_device =
951 list_entry(pos, me_device_t, list);
952 o_device->
953 me_device_query_info_device
954 (o_device, &o_vendor_id,
955 &o_device_id, &o_serial_no,
956 &o_bus_type, &o_bus_no, &o_dev_no,
957 &o_func_no, &o_plugged);
958
959 if (cfg_setup.device_list[i].info.
960 hw_location.bus_type ==
961 ME_BUS_TYPE_PCI) {
962 if (((o_vendor_id ==
963 cfg_setup.device_list[i].
964 info.vendor_id)
965 && (o_device_id ==
966 cfg_setup.
967 device_list[i].info.
968 device_id)
969 && (o_serial_no ==
970 cfg_setup.
971 device_list[i].info.
972 serial_no)
973 && (o_bus_type ==
974 cfg_setup.
975 device_list[i].info.
976 hw_location.bus_type))
977 ||
978 ((o_vendor_id ==
979 cfg_setup.device_list[i].
980 info.vendor_id)
981 && (o_device_id ==
982 cfg_setup.
983 device_list[i].info.
984 device_id)
985 && (o_bus_type ==
986 cfg_setup.
987 device_list[i].info.
988 hw_location.bus_type)
989 && (o_bus_no ==
990 cfg_setup.
991 device_list[i].info.
992 hw_location.pci.bus_no)
993 && (o_dev_no ==
994 cfg_setup.
995 device_list[i].info.
996 hw_location.pci.
997 device_no)
998 && (o_func_no ==
999 cfg_setup.
1000 device_list[i].info.
1001 hw_location.pci.
1002 function_no))) {
1003 list_move_tail(pos,
1004 &new_list);
1005 break;
1006 }
1007 }
1008/*
1009 else if (cfg_setup.device_list[i].info.hw_location.bus_type == ME_BUS_TYPE_USB)
1010 {
1011 if (((o_vendor_id == cfg_setup.device_list[i].info.vendor_id) &&
1012 (o_device_id == cfg_setup.device_list[i].info.device_id) &&
1013 (o_serial_no == cfg_setup.device_list[i].info.serial_no) &&
1014 (o_bus_type == cfg_setup.device_list[i].info.hw_location.bus_type)) ||
1015 ((o_vendor_id == cfg_setup.device_list[i].info.vendor_id) &&
1016 (o_device_id == cfg_setup.device_list[i].info.device_id) &&
1017 (o_bus_type == cfg_setup.device_list[i].info.hw_location.bus_type) &&
1018 (o_bus_no == cfg_setup.device_list[i].info.hw_location.usb.root_hub_no)))
1019 {
1020 list_move_tail(pos, &new_list);
1021 break;
1022 }
1023 }
1024*/
1025 else {
1026 PERROR("Wrong bus type: %d.\n",
1027 cfg_setup.device_list[i].
1028 info.hw_location.
1029 bus_type);
1030 }
1031 }
1032
1033 if (pos == &me_device_list) { // Device is not already in the list
1034 if (cfg_setup.device_list[i].info.
1035 hw_location.bus_type ==
1036 ME_BUS_TYPE_PCI) {
1037 n_device =
1038 get_dummy_instance
1039 (cfg_setup.device_list[i].
1040 info.vendor_id,
1041 cfg_setup.device_list[i].
1042 info.device_id,
1043 cfg_setup.device_list[i].
1044 info.serial_no,
1045 cfg_setup.device_list[i].
1046 info.hw_location.bus_type,
1047 cfg_setup.device_list[i].
1048 info.hw_location.pci.
1049 bus_no,
1050 cfg_setup.device_list[i].
1051 info.hw_location.pci.
1052 device_no,
1053 cfg_setup.device_list[i].
1054 info.hw_location.pci.
1055 function_no);
1056
1057 if (!n_device) {
1058 PERROR
1059 ("Can't get dummy instance.\n");
1060 kfree(cfg_setup.
1061 device_list);
1062 spin_lock(&me_lock);
1063 me_count--;
1064 spin_unlock(&me_lock);
1065 up_write(&me_rwsem);
1066 return -EFAULT;
1067 }
1068
1069 list_add_tail(&n_device->list,
1070 &new_list);
1071 }
1072/*
1073 else if (cfg_setup.device_list[i].info.hw_location.bus_type == ME_BUS_TYPE_USB)
1074 {
1075 n_device = get_dummy_instance(
1076 cfg_setup.device_list[i].info.vendor_id,
1077 cfg_setup.device_list[i].info.device_id,
1078 cfg_setup.device_list[i].info.serial_no,
1079 cfg_setup.device_list[i].info.hw_location.bus_type,
1080 cfg_setup.device_list[i].info.hw_location.usb.root_hub_no,
1081 0,
1082 0);
1083
1084 if (!n_device)
1085 {
1086 PERROR("Can't get dummy instance.\n");
1087 kfree(cfg_setup.device_list);
1088 spin_lock(&me_lock);
1089 me_count--;
1090 spin_unlock(&me_lock);
1091 up_write(&me_rwsem);
1092 return -EFAULT;
1093 }
1094
1095 list_add_tail(&n_device->list, &new_list);
1096 }
1097*/
1098 }
1099 } else {
1100 n_device = get_dummy_instance(0,
1101 0, 0, 0, 0, 0, 0);
1102
1103 if (!n_device) {
1104 PERROR("Can't get dummy instance.\n");
1105 kfree(cfg_setup.device_list);
1106 spin_lock(&me_lock);
1107 me_count--;
1108 spin_unlock(&me_lock);
1109 up_write(&me_rwsem);
1110 return -EFAULT;
1111 }
1112
1113 list_add_tail(&n_device->list, &new_list);
1114 }
1115 }
1116
1117 while (!list_empty(&me_device_list)) {
1118 o_device =
1119 list_entry(me_device_list.next, me_device_t, list);
1120 o_device->me_device_query_info_device(o_device,
1121 &o_vendor_id,
1122 &o_device_id,
1123 &o_serial_no,
1124 &o_bus_type,
1125 &o_bus_no,
1126 &o_dev_no,
1127 &o_func_no,
1128 &o_plugged);
1129
1130 if (o_plugged == ME_PLUGGED_IN) {
1131 list_move_tail(me_device_list.next, &new_list);
1132 } else {
1133 list_del(me_device_list.next);
1134 release_instance(o_device);
1135 }
1136 }
1137
1138 // Move temporary new list to global driver list.
1139 list_splice(&new_list, &me_device_list);
1140
1141 karg_cfg_setup.errno = ME_ERRNO_SUCCESS;
1142 }
1143
1144 for (i = 0; i < cfg_setup.count; i++) {
1145
1146 karg_cfg_setup.errno =
1147 me_config_load_device(filep, &cfg_setup.device_list[i], i);
1148 if (karg_cfg_setup.errno) {
1149 PERROR("me_config_load_device(%d)=%d\n", i,
1150 karg_cfg_setup.errno);
1151 break;
1152 }
1153 }
1154
1155 spin_lock(&me_lock);
1156
1157 me_count--;
1158 spin_unlock(&me_lock);
1159 up_write(&me_rwsem);
1160
1161 err = copy_to_user(arg, &karg_cfg_setup, sizeof(me_config_load_t));
1162
1163 if (err) {
1164 PERROR("Can't copy config list to user space.\n");
1165 kfree(cfg_setup.device_list);
1166 return -EFAULT;
1167 }
1168
1169 kfree(cfg_setup.device_list);
1170 return 0;
1171}
1172
1173static int me_io_stream_start(struct file *filep, me_io_stream_start_t * arg)
1174{
1175 int err;
1176 int i, k;
1177
1178 struct list_head *pos;
1179 me_device_t *device;
1180 me_io_stream_start_t karg;
1181 meIOStreamStart_t *list;
1182
1183 PDEBUG("executed.\n");
1184
1185 err = copy_from_user(&karg, arg, sizeof(me_io_stream_start_t));
1186
1187 if (err) {
1188 PERROR("Can't copy arguments to kernel space.\n");
1189 return -EFAULT;
1190 }
1191
1192 karg.errno = ME_ERRNO_SUCCESS;
1193
1194 list = kmalloc(sizeof(meIOStreamStart_t) * karg.count, GFP_KERNEL);
1195
1196 if (!list) {
1197 PERROR("Can't get buffer for start list.\n");
1198 return -ENOMEM;
1199 }
1200
1201 err =
1202 copy_from_user(list, karg.start_list,
1203 sizeof(meIOStreamStart_t) * karg.count);
1204
1205 if (err) {
1206 PERROR("Can't copy start list to kernel space.\n");
1207 kfree(list);
1208 return -EFAULT;
1209 }
1210
1211 spin_lock(&me_lock);
1212
1213 if ((me_filep != NULL) && (me_filep != filep)) {
1214 spin_unlock(&me_lock);
1215 PERROR("Driver System is logged by another process.\n");
1216
1217 for (i = 0; i < karg.count; i++) {
1218 list[i].iErrno = ME_ERRNO_LOCKED;
1219 }
1220 } else {
1221 me_count++;
1222 spin_unlock(&me_lock);
1223
1224 for (i = 0; i < karg.count; i++) {
1225 down_read(&me_rwsem);
1226 k = 0;
1227 list_for_each(pos, &me_device_list) {
1228 if (k == list[i].iDevice) {
1229 device =
1230 list_entry(pos, me_device_t, list);
1231 break;
1232 }
1233
1234 k++;
1235 }
1236
1237 if (pos == &me_device_list) {
1238 up_read(&me_rwsem);
1239 PERROR("Invalid device number specified.\n");
1240 list[i].iErrno = ME_ERRNO_INVALID_DEVICE;
1241 karg.errno = ME_ERRNO_INVALID_DEVICE;
1242 break;
1243 } else {
1244 list[i].iErrno =
1245 device->me_device_io_stream_start(device,
1246 filep,
1247 list[i].
1248 iSubdevice,
1249 list[i].
1250 iStartMode,
1251 list[i].
1252 iTimeOut,
1253 list[i].
1254 iFlags);
1255
1256 if (list[i].iErrno) {
1257 up_read(&me_rwsem);
1258 karg.errno = list[i].iErrno;
1259 break;
1260 }
1261 }
1262
1263 up_read(&me_rwsem);
1264 }
1265
1266 spin_lock(&me_lock);
1267
1268 me_count--;
1269 spin_unlock(&me_lock);
1270 }
1271
1272 err = copy_to_user(arg, &karg, sizeof(me_io_stream_start_t));
1273
1274 if (err) {
1275 PERROR("Can't copy arguments to user space.\n");
1276 kfree(list);
1277 return -EFAULT;
1278 }
1279
1280 err =
1281 copy_to_user(karg.start_list, list,
1282 sizeof(meIOStreamStart_t) * karg.count);
1283
1284 if (err) {
1285 PERROR("Can't copy start list to user space.\n");
1286 kfree(list);
1287 return -EFAULT;
1288 }
1289
1290 kfree(list);
1291
1292 return err;
1293}
1294
1295static int me_io_single(struct file *filep, me_io_single_t * arg)
1296{
1297 int err;
1298 int i, k;
1299
1300 struct list_head *pos;
1301 me_device_t *device;
1302 me_io_single_t karg;
1303 meIOSingle_t *list;
1304
1305 PDEBUG("executed.\n");
1306
1307 err = copy_from_user(&karg, arg, sizeof(me_io_single_t));
1308
1309 if (err) {
1310 PERROR("Can't copy arguments to kernel space.\n");
1311 return -EFAULT;
1312 }
1313
1314 karg.errno = ME_ERRNO_SUCCESS;
1315
1316 list = kmalloc(sizeof(meIOSingle_t) * karg.count, GFP_KERNEL);
1317
1318 if (!list) {
1319 PERROR("Can't get buffer for single list.\n");
1320 return -ENOMEM;
1321 }
1322
1323 err =
1324 copy_from_user(list, karg.single_list,
1325 sizeof(meIOSingle_t) * karg.count);
1326
1327 if (err) {
1328 PERROR("Can't copy single list to kernel space.\n");
1329 kfree(list);
1330 return -EFAULT;
1331 }
1332
1333 spin_lock(&me_lock);
1334
1335 if ((me_filep != NULL) && (me_filep != filep)) {
1336 spin_unlock(&me_lock);
1337 PERROR("Driver System is logged by another process.\n");
1338
1339 for (i = 0; i < karg.count; i++) {
1340 list[i].iErrno = ME_ERRNO_LOCKED;
1341 }
1342 } else {
1343 me_count++;
1344 spin_unlock(&me_lock);
1345
1346 for (i = 0; i < karg.count; i++) {
1347 k = 0;
1348
1349 down_read(&me_rwsem);
1350
1351 list_for_each(pos, &me_device_list) {
1352 if (k == list[i].iDevice) {
1353 device =
1354 list_entry(pos, me_device_t, list);
1355 break;
1356 }
1357
1358 k++;
1359 }
1360
1361 if (pos == &me_device_list) {
1362 up_read(&me_rwsem);
1363 PERROR("Invalid device number specified.\n");
1364 list[i].iErrno = ME_ERRNO_INVALID_DEVICE;
1365 karg.errno = ME_ERRNO_INVALID_DEVICE;
1366 break;
1367 } else {
1368 if (list[i].iDir == ME_DIR_OUTPUT) {
1369 list[i].iErrno =
1370 device->
1371 me_device_io_single_write(device,
1372 filep,
1373 list[i].
1374 iSubdevice,
1375 list[i].
1376 iChannel,
1377 list[i].
1378 iValue,
1379 list[i].
1380 iTimeOut,
1381 list[i].
1382 iFlags);
1383
1384 if (list[i].iErrno) {
1385 up_read(&me_rwsem);
1386 karg.errno = list[i].iErrno;
1387 break;
1388 }
1389 } else if (list[i].iDir == ME_DIR_INPUT) {
1390 list[i].iErrno =
1391 device->
1392 me_device_io_single_read(device,
1393 filep,
1394 list[i].
1395 iSubdevice,
1396 list[i].
1397 iChannel,
1398 &list[i].
1399 iValue,
1400 list[i].
1401 iTimeOut,
1402 list[i].
1403 iFlags);
1404
1405 if (list[i].iErrno) {
1406 up_read(&me_rwsem);
1407 karg.errno = list[i].iErrno;
1408 break;
1409 }
1410 } else {
1411 up_read(&me_rwsem);
1412 PERROR
1413 ("Invalid single direction specified.\n");
1414 list[i].iErrno = ME_ERRNO_INVALID_DIR;
1415 karg.errno = ME_ERRNO_INVALID_DIR;
1416 break;
1417 }
1418 }
1419
1420 up_read(&me_rwsem);
1421 }
1422
1423 spin_lock(&me_lock);
1424
1425 me_count--;
1426 spin_unlock(&me_lock);
1427 }
1428
1429 err = copy_to_user(arg, &karg, sizeof(me_io_single_t));
1430
1431 if (err) {
1432 PERROR("Can't copy arguments to user space.\n");
1433 return -EFAULT;
1434 }
1435
1436 err =
1437 copy_to_user(karg.single_list, list,
1438 sizeof(meIOSingle_t) * karg.count);
1439
1440 if (err) {
1441 PERROR("Can't copy single list to user space.\n");
1442 kfree(list);
1443 return -EFAULT;
1444 }
1445
1446 kfree(list);
1447
1448 return err;
1449}
1450
1451static int me_io_stream_config(struct file *filep, me_io_stream_config_t * arg)
1452{
1453 int err;
1454 int k = 0;
1455
1456 struct list_head *pos;
1457 me_device_t *device;
1458 me_io_stream_config_t karg;
1459 meIOStreamConfig_t *list;
1460
1461 PDEBUG("executed.\n");
1462
1463 err = copy_from_user(&karg, arg, sizeof(me_io_stream_config_t));
1464
1465 if (err) {
1466 PERROR("Can't copy arguments to kernel space.\n");
1467 return -EFAULT;
1468 }
1469
1470 list = kmalloc(sizeof(meIOStreamConfig_t) * karg.count, GFP_KERNEL);
1471
1472 if (!list) {
1473 PERROR("Can't get buffer for config list.\n");
1474 return -ENOMEM;
1475 }
1476
1477 err =
1478 copy_from_user(list, karg.config_list,
1479 sizeof(meIOStreamConfig_t) * karg.count);
1480
1481 if (err) {
1482 PERROR("Can't copy config list to kernel space.\n");
1483 kfree(list);
1484 return -EFAULT;
1485 }
1486
1487 spin_lock(&me_lock);
1488
1489 if ((me_filep != NULL) && (me_filep != filep)) {
1490 spin_unlock(&me_lock);
1491 PERROR("Driver System is logged by another process.\n");
1492 karg.errno = ME_ERRNO_LOCKED;
1493 } else {
1494 me_count++;
1495 spin_unlock(&me_lock);
1496
1497 down_read(&me_rwsem);
1498
1499 list_for_each(pos, &me_device_list) {
1500 if (k == karg.device) {
1501 device = list_entry(pos, me_device_t, list);
1502 break;
1503 }
1504
1505 k++;
1506 }
1507
1508 if (pos == &me_device_list) {
1509 PERROR("Invalid device number specified.\n");
1510 karg.errno = ME_ERRNO_INVALID_DEVICE;
1511 } else {
1512 karg.errno =
1513 device->me_device_io_stream_config(device, filep,
1514 karg.subdevice,
1515 list, karg.count,
1516 &karg.trigger,
1517 karg.
1518 fifo_irq_threshold,
1519 karg.flags);
1520 }
1521
1522 up_read(&me_rwsem);
1523
1524 spin_lock(&me_lock);
1525 me_count--;
1526 spin_unlock(&me_lock);
1527 }
1528
1529 err = copy_to_user(arg, &karg, sizeof(me_io_stream_config_t));
1530
1531 if (err) {
1532 PERROR("Can't copy back to user space.\n");
1533 kfree(list);
1534 return -EFAULT;
1535 }
1536
1537 kfree(list);
1538
1539 return err;
1540}
1541
1542static int me_query_number_devices(struct file *filep,
1543 me_query_number_devices_t * arg)
1544{
1545 int err;
1546 me_query_number_devices_t karg;
1547
1548 struct list_head *pos;
1549
1550 PDEBUG("executed.\n");
1551
1552 karg.number = 0;
1553 down_read(&me_rwsem);
1554 list_for_each(pos, &me_device_list) {
1555 karg.number++;
1556 }
1557
1558 up_read(&me_rwsem);
1559
1560 karg.errno = ME_ERRNO_SUCCESS;
1561
1562 err = copy_to_user(arg, &karg, sizeof(me_query_number_devices_t));
1563
1564 if (err) {
1565 PERROR("Can't copy query back to user space.\n");
1566 return -EFAULT;
1567 }
1568
1569 return 0;
1570}
1571
1572static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t * arg)
1573{
1574 int err;
1575 int i, k;
1576
1577 struct list_head *pos;
1578 me_device_t *device;
1579 me_io_stream_stop_t karg;
1580 meIOStreamStop_t *list;
1581
1582 PDEBUG("executed.\n");
1583
1584 err = copy_from_user(&karg, arg, sizeof(me_io_stream_stop_t));
1585
1586 if (err) {
1587 PERROR("Can't copy arguments to kernel space.\n");
1588 return -EFAULT;
1589 }
1590
1591 karg.errno = ME_ERRNO_SUCCESS;
1592
1593 list = kmalloc(sizeof(meIOStreamStop_t) * karg.count, GFP_KERNEL);
1594
1595 if (!list) {
1596 PERROR("Can't get buffer for stop list.\n");
1597 return -ENOMEM;
1598 }
1599
1600 err =
1601 copy_from_user(list, karg.stop_list,
1602 sizeof(meIOStreamStop_t) * karg.count);
1603
1604 if (err) {
1605 PERROR("Can't copy stop list to kernel space.\n");
1606 kfree(list);
1607 return -EFAULT;
1608 }
1609
1610 spin_lock(&me_lock);
1611
1612 if ((me_filep != NULL) && (me_filep != filep)) {
1613 spin_unlock(&me_lock);
1614 PERROR("Driver System is logged by another process.\n");
1615
1616 for (i = 0; i < karg.count; i++) {
1617 list[i].iErrno = ME_ERRNO_LOCKED;
1618 }
1619 } else {
1620 me_count++;
1621 spin_unlock(&me_lock);
1622
1623 for (i = 0; i < karg.count; i++) {
1624 k = 0;
1625 down_read(&me_rwsem);
1626 list_for_each(pos, &me_device_list) {
1627 if (k == list[i].iDevice) {
1628 device =
1629 list_entry(pos, me_device_t, list);
1630 break;
1631 }
1632
1633 k++;
1634 }
1635
1636 if (pos == &me_device_list) {
1637 up_read(&me_rwsem);
1638 PERROR("Invalid device number specified.\n");
1639 list[i].iErrno = ME_ERRNO_INVALID_DEVICE;
1640 karg.errno = ME_ERRNO_INVALID_DEVICE;
1641 break;
1642 } else {
1643 list[i].iErrno =
1644 device->me_device_io_stream_stop(device,
1645 filep,
1646 list[i].
1647 iSubdevice,
1648 list[i].
1649 iStopMode,
1650 list[i].
1651 iFlags);
1652
1653 if (list[i].iErrno) {
1654 up_read(&me_rwsem);
1655 karg.errno = list[i].iErrno;
1656 break;
1657 }
1658 }
1659
1660 up_read(&me_rwsem);
1661 }
1662
1663 spin_lock(&me_lock);
1664
1665 me_count--;
1666 spin_unlock(&me_lock);
1667 }
1668
1669 err = copy_to_user(arg, &karg, sizeof(me_io_stream_stop_t));
1670
1671 if (err) {
1672 PERROR("Can't copy arguments to user space.\n");
1673 return -EFAULT;
1674 }
1675
1676 err =
1677 copy_to_user(karg.stop_list, list,
1678 sizeof(meIOStreamStop_t) * karg.count);
1679
1680 if (err) {
1681 PERROR("Can't copy stop list to user space.\n");
1682 kfree(list);
1683 return -EFAULT;
1684 }
1685
1686 kfree(list);
1687
1688 return err;
1689}
1690
1691/* //me_probe_usb
1692static int me_probe_usb(struct usb_interface *interface, const struct usb_device_id *id)
1693{
1694 //int err;
1695 //me_usb_constructor_t *constructor = NULL;
1696 me_device_t *n_device = NULL;
1697
1698 PDEBUG("executed.\n");
1699
1700 switch (id->idProduct)
1701 {
1702 case USB_DEVICE_ID_MEPHISTO_S1:
1703 if((constructor = symbol_get(mephisto_s1_constructor)) == NULL){
1704 err = request_module(MEPHISTO_S1_NAME);
1705 if(err){
1706 PERROR("Error while request for module %s.\n", MEPHISTO_S1_NAME);
1707 return -ENODEV;
1708 }
1709 if((constructor = symbol_get(mephisto_s1_constructor)) == NULL){
1710 PERROR("Can't get %s driver module constructor.\n", MEPHISTO_S1_NAME);
1711 return -ENODEV;
1712 }
1713 }
1714
1715 if((n_device = (*constructor)(interface)) == NULL){
1716 symbol_put(mephisto_s1_constructor);
1717 PERROR("Can't get device instance of %s driver module.\n", MEPHISTO_S1_NAME);
1718 return -ENODEV;
1719 }
1720
1721 break;
1722
1723 default:
1724 PERROR("Invalid product id.\n");
1725
1726 return -EINVAL;
1727 }
1728
1729 return insert_to_device_list(n_device);
1730}
1731*/
1732
1733/* //me_disconnect_usb
1734static void me_disconnect_usb(struct usb_interface *interface)
1735{
1736
1737 struct usb_device *device = interface_to_usbdev(interface);
1738 int vendor_id = device->descriptor.idVendor;
1739 int device_id = device->descriptor.idProduct;
1740 int serial_no;
1741
1742 sscanf(&device->serial[2], "%x", &serial_no);
1743
1744 PDEBUG("executed.\n");
1745
1746 PINFO("Vendor id = 0x%08X\n", vendor_id);
1747 PINFO("Device id = 0x%08X\n", device_id);
1748 PINFO("Serial Number = 0x%08X\n", serial_no);
1749
1750 replace_with_dummy(vendor_id, device_id, serial_no);
1751}
1752*/
1753
1754static int me_ioctl(struct inode *inodep,
1755 struct file *filep, unsigned int service, unsigned long arg)
1756{
1757
1758 PDEBUG("executed.\n");
1759
1760 if (_IOC_TYPE(service) != MEMAIN_MAGIC) {
1761 PERROR("Invalid magic number.\n");
1762 return -ENOTTY;
1763 }
1764
1765 PDEBUG("service number: 0x%x.\n", service);
1766
1767 switch (service) {
1768 case ME_IO_IRQ_ENABLE:
1769 return me_io_irq_start(filep, (me_io_irq_start_t *) arg);
1770
1771 case ME_IO_IRQ_WAIT:
1772 return me_io_irq_wait(filep, (me_io_irq_wait_t *) arg);
1773
1774 case ME_IO_IRQ_DISABLE:
1775 return me_io_irq_stop(filep, (me_io_irq_stop_t *) arg);
1776
1777 case ME_IO_RESET_DEVICE:
1778 return me_io_reset_device(filep, (me_io_reset_device_t *) arg);
1779
1780 case ME_IO_RESET_SUBDEVICE:
1781 return me_io_reset_subdevice(filep,
1782 (me_io_reset_subdevice_t *) arg);
1783
1784 case ME_IO_SINGLE_CONFIG:
1785 return me_io_single_config(filep,
1786 (me_io_single_config_t *) arg);
1787
1788 case ME_IO_SINGLE:
1789 return me_io_single(filep, (me_io_single_t *) arg);
1790
1791 case ME_IO_STREAM_CONFIG:
1792 return me_io_stream_config(filep,
1793 (me_io_stream_config_t *) arg);
1794
1795 case ME_IO_STREAM_NEW_VALUES:
1796 return me_io_stream_new_values(filep,
1797 (me_io_stream_new_values_t *)
1798 arg);
1799
1800 case ME_IO_STREAM_READ:
1801 return me_io_stream_read(filep, (me_io_stream_read_t *) arg);
1802
1803 case ME_IO_STREAM_START:
1804 return me_io_stream_start(filep, (me_io_stream_start_t *) arg);
1805
1806 case ME_IO_STREAM_STATUS:
1807 return me_io_stream_status(filep,
1808 (me_io_stream_status_t *) arg);
1809
1810 case ME_IO_STREAM_STOP:
1811 return me_io_stream_stop(filep, (me_io_stream_stop_t *) arg);
1812
1813 case ME_IO_STREAM_WRITE:
1814 return me_io_stream_write(filep, (me_io_stream_write_t *) arg);
1815
1816 case ME_LOCK_DRIVER:
1817 return me_lock_driver(filep, (me_lock_driver_t *) arg);
1818
1819 case ME_LOCK_DEVICE:
1820 return me_lock_device(filep, (me_lock_device_t *) arg);
1821
1822 case ME_LOCK_SUBDEVICE:
1823 return me_lock_subdevice(filep, (me_lock_subdevice_t *) arg);
1824
1825 case ME_QUERY_INFO_DEVICE:
1826 return me_query_info_device(filep,
1827 (me_query_info_device_t *) arg);
1828
1829 case ME_QUERY_DESCRIPTION_DEVICE:
1830 return me_query_description_device(filep,
1831 (me_query_description_device_t
1832 *) arg);
1833
1834 case ME_QUERY_NAME_DEVICE:
1835 return me_query_name_device(filep,
1836 (me_query_name_device_t *) arg);
1837
1838 case ME_QUERY_NAME_DEVICE_DRIVER:
1839 return me_query_name_device_driver(filep,
1840 (me_query_name_device_driver_t
1841 *) arg);
1842
1843 case ME_QUERY_NUMBER_DEVICES:
1844 return me_query_number_devices(filep,
1845 (me_query_number_devices_t *)
1846 arg);
1847
1848 case ME_QUERY_NUMBER_SUBDEVICES:
1849 return me_query_number_subdevices(filep,
1850 (me_query_number_subdevices_t
1851 *) arg);
1852
1853 case ME_QUERY_NUMBER_CHANNELS:
1854 return me_query_number_channels(filep,
1855 (me_query_number_channels_t *)
1856 arg);
1857
1858 case ME_QUERY_NUMBER_RANGES:
1859 return me_query_number_ranges(filep,
1860 (me_query_number_ranges_t *) arg);
1861
1862 case ME_QUERY_RANGE_BY_MIN_MAX:
1863 return me_query_range_by_min_max(filep,
1864 (me_query_range_by_min_max_t *)
1865 arg);
1866
1867 case ME_QUERY_RANGE_INFO:
1868 return me_query_range_info(filep,
1869 (me_query_range_info_t *) arg);
1870
1871 case ME_QUERY_SUBDEVICE_BY_TYPE:
1872 return me_query_subdevice_by_type(filep,
1873 (me_query_subdevice_by_type_t
1874 *) arg);
1875
1876 case ME_QUERY_SUBDEVICE_TYPE:
1877 return me_query_subdevice_type(filep,
1878 (me_query_subdevice_type_t *)
1879 arg);
1880
1881 case ME_QUERY_SUBDEVICE_CAPS:
1882 return me_query_subdevice_caps(filep,
1883 (me_query_subdevice_caps_t *)
1884 arg);
1885
1886 case ME_QUERY_SUBDEVICE_CAPS_ARGS:
1887 return me_query_subdevice_caps_args(filep,
1888 (me_query_subdevice_caps_args_t
1889 *) arg);
1890
1891 case ME_QUERY_TIMER:
1892 return me_query_timer(filep, (me_query_timer_t *) arg);
1893
1894 case ME_QUERY_VERSION_MAIN_DRIVER:
1895 return me_query_version_main_driver(filep,
1896 (me_query_version_main_driver_t
1897 *) arg);
1898
1899 case ME_QUERY_VERSION_DEVICE_DRIVER:
1900 return me_query_version_device_driver(filep,
1901 (me_query_version_device_driver_t
1902 *) arg);
1903
1904 case ME_CONFIG_LOAD:
1905 return me_config_load(filep, (me_config_load_t *) arg);
1906 }
1907
1908 PERROR("Invalid ioctl number.\n");
1909 return -ENOTTY;
1910}
1911
1912// Init and exit of module.
1913static int memain_init(void)
1914{
1915 int result = 0;
1916 dev_t dev = MKDEV(major, 0);
1917
1918 PDEBUG("executed.\n");
1919
1920 // Register pci driver. This will return 0 if the PCI subsystem is not available.
1921 result = pci_register_driver(&me_pci_driver);
1922
1923 if (result < 0) {
1924 PERROR("Can't register pci driver.\n");
1925 goto INIT_ERROR_1;
1926 }
1927
1928/*
1929 // Register usb driver. This will return -ENODEV if no USB subsystem is available.
1930 result = usb_register(&me_usb_driver);
1931
1932 if (result)
1933 {
1934 if (result == -ENODEV)
1935 {
1936 PERROR("No USB subsystem available.\n");
1937 }
1938 else
1939 {
1940 PERROR("Can't register usb driver.\n");
1941 goto INIT_ERROR_2;
1942 }
1943 }
1944*/
1945 // Register the character device.
1946 if (major) {
1947 result = register_chrdev_region(dev, 1, MEMAIN_NAME);
1948 } else {
1949 result = alloc_chrdev_region(&dev, 0, 1, MEMAIN_NAME);
1950 major = MAJOR(dev);
1951 }
1952
1953 if (result < 0) {
1954 PERROR("Can't get major driver no.\n");
1955 goto INIT_ERROR_3;
1956 }
1957
1958 cdevp = cdev_alloc();
1959
1960 if (!cdevp) {
1961 PERROR("Can't get character device structure.\n");
1962 result = -ENOMEM;
1963 goto INIT_ERROR_4;
1964 }
1965
1966 cdevp->ops = &me_file_operations;
1967
1968 cdevp->owner = THIS_MODULE;
1969
1970 result = cdev_add(cdevp, dev, 1);
1971
1972 if (result < 0) {
1973 PERROR("Cannot add character device structure.\n");
1974 goto INIT_ERROR_5;
1975 }
1976
1977 return 0;
1978
1979 INIT_ERROR_5:
1980 cdev_del(cdevp);
1981
1982 INIT_ERROR_4:
1983 unregister_chrdev_region(dev, 1);
1984
1985 INIT_ERROR_3:
1986// usb_deregister(&me_usb_driver);
1987
1988//INIT_ERROR_2:
1989 pci_unregister_driver(&me_pci_driver);
1990 clear_device_list();
1991
1992 INIT_ERROR_1:
1993 return result;
1994}
1995
1996static void __exit memain_exit(void)
1997{
1998 dev_t dev = MKDEV(major, 0);
1999
2000 PDEBUG("executed.\n");
2001
2002 cdev_del(cdevp);
2003 unregister_chrdev_region(dev, 1);
2004 pci_unregister_driver(&me_pci_driver);
2005// usb_deregister(&me_usb_driver);
2006 clear_device_list();
2007}
2008
2009module_init(memain_init);
2010module_exit(memain_exit);
2011
2012// Administrative stuff for modinfo.
2013MODULE_AUTHOR
2014 ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
2015MODULE_DESCRIPTION("Central module for Meilhaus Driver System.");
2016MODULE_SUPPORTED_DEVICE("Meilhaus PCI/cPCI boards.");
2017MODULE_LICENSE("GPL");
2018
2019#ifdef BOSCH
2020// Export the flag for the BOSCH firmware.
2021EXPORT_SYMBOL(me_bosch_fw);
2022#endif // BOSCH
diff --git a/drivers/staging/meilhaus/memain.h b/drivers/staging/meilhaus/memain.h
new file mode 100644
index 000000000000..7616ff7f65cb
--- /dev/null
+++ b/drivers/staging/meilhaus/memain.h
@@ -0,0 +1,460 @@
1/*
2 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File : memain.h
5 * Author : GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
6 */
7
8#ifndef _MEMAIN_H_
9#define _MEMAIN_H_
10
11#include "meinternal.h"
12
13#include "meids.h"
14#include "medebug.h"
15
16#include "medevice.h"
17/*#include "me1000_device.h"
18#include "me1400_device.h"
19#include "me1600_device.h"*/
20#include "me4600_device.h"
21/*#include "me6000_device.h"
22#include "me0600_device.h"
23#include "me8100_device.h"
24#include "me8200_device.h"
25#include "me0900_device.h"*/
26#include "medummy.h"
27
28#ifdef __KERNEL__
29
30/*=============================================================================
31 PCI device table.
32 This is used by modprobe to translate PCI IDs to drivers.
33 ===========================================================================*/
34
35static struct pci_device_id me_pci_table[] __devinitdata = {
36 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000, PCI_ANY_ID,
37 PCI_ANY_ID, 0, 0, 0},
38 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000_A, PCI_ANY_ID,
39 PCI_ANY_ID, 0, 0, 0},
40 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000_B, PCI_ANY_ID,
41 PCI_ANY_ID, 0, 0, 0},
42
43 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1400, PCI_ANY_ID,
44 PCI_ANY_ID, 0, 0, 0},
45 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140A, PCI_ANY_ID,
46 PCI_ANY_ID, 0, 0, 0},
47 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140B, PCI_ANY_ID,
48 PCI_ANY_ID, 0, 0, 0},
49 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14E0, PCI_ANY_ID,
50 PCI_ANY_ID, 0, 0, 0},
51 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14EA, PCI_ANY_ID,
52 PCI_ANY_ID, 0, 0, 0},
53 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14EB, PCI_ANY_ID,
54 PCI_ANY_ID, 0, 0, 0},
55 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140C, PCI_ANY_ID,
56 PCI_ANY_ID, 0, 0, 0},
57 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140D, PCI_ANY_ID,
58 PCI_ANY_ID, 0, 0, 0},
59
60 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_4U, PCI_ANY_ID,
61 PCI_ANY_ID, 0, 0, 0},
62 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_8U, PCI_ANY_ID,
63 PCI_ANY_ID, 0, 0, 0},
64 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_12U, PCI_ANY_ID,
65 PCI_ANY_ID, 0, 0, 0},
66 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_16U, PCI_ANY_ID,
67 PCI_ANY_ID, 0, 0, 0},
68 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I,
69 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
70
71 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4610, PCI_ANY_ID,
72 PCI_ANY_ID, 0, 0, 0},
73 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4650, PCI_ANY_ID,
74 PCI_ANY_ID, 0, 0, 0},
75 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660, PCI_ANY_ID,
76 PCI_ANY_ID, 0, 0, 0},
77 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660I, PCI_ANY_ID,
78 PCI_ANY_ID, 0, 0, 0},
79 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670, PCI_ANY_ID,
80 PCI_ANY_ID, 0, 0, 0},
81 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670I, PCI_ANY_ID,
82 PCI_ANY_ID, 0, 0, 0},
83 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670S, PCI_ANY_ID,
84 PCI_ANY_ID, 0, 0, 0},
85 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670IS, PCI_ANY_ID,
86 PCI_ANY_ID, 0, 0, 0},
87 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680, PCI_ANY_ID,
88 PCI_ANY_ID, 0, 0, 0},
89 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680I, PCI_ANY_ID,
90 PCI_ANY_ID, 0, 0, 0},
91 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680S, PCI_ANY_ID,
92 PCI_ANY_ID, 0, 0, 0},
93 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680IS, PCI_ANY_ID,
94 PCI_ANY_ID, 0, 0, 0},
95
96 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6004, PCI_ANY_ID,
97 PCI_ANY_ID, 0, 0, 0},
98 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6008, PCI_ANY_ID,
99 PCI_ANY_ID, 0, 0, 0},
100 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME600F, PCI_ANY_ID,
101 PCI_ANY_ID, 0, 0, 0},
102
103 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6014, PCI_ANY_ID,
104 PCI_ANY_ID, 0, 0, 0},
105 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6018, PCI_ANY_ID,
106 PCI_ANY_ID, 0, 0, 0},
107 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME601F, PCI_ANY_ID,
108 PCI_ANY_ID, 0, 0, 0},
109
110 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6034, PCI_ANY_ID,
111 PCI_ANY_ID, 0, 0, 0},
112 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6038, PCI_ANY_ID,
113 PCI_ANY_ID, 0, 0, 0},
114 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME603F, PCI_ANY_ID,
115 PCI_ANY_ID, 0, 0, 0},
116
117 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6104, PCI_ANY_ID,
118 PCI_ANY_ID, 0, 0, 0},
119 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6108, PCI_ANY_ID,
120 PCI_ANY_ID, 0, 0, 0},
121 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME610F, PCI_ANY_ID,
122 PCI_ANY_ID, 0, 0, 0},
123
124 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6114, PCI_ANY_ID,
125 PCI_ANY_ID, 0, 0, 0},
126 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6118, PCI_ANY_ID,
127 PCI_ANY_ID, 0, 0, 0},
128 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME611F, PCI_ANY_ID,
129 PCI_ANY_ID, 0, 0, 0},
130
131 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6134, PCI_ANY_ID,
132 PCI_ANY_ID, 0, 0, 0},
133 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6138, PCI_ANY_ID,
134 PCI_ANY_ID, 0, 0, 0},
135 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME613F, PCI_ANY_ID,
136 PCI_ANY_ID, 0, 0, 0},
137
138 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6044, PCI_ANY_ID,
139 PCI_ANY_ID, 0, 0, 0},
140 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6048, PCI_ANY_ID,
141 PCI_ANY_ID, 0, 0, 0},
142 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME604F, PCI_ANY_ID,
143 PCI_ANY_ID, 0, 0, 0},
144
145 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6054, PCI_ANY_ID,
146 PCI_ANY_ID, 0, 0, 0},
147 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6058, PCI_ANY_ID,
148 PCI_ANY_ID, 0, 0, 0},
149 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME605F, PCI_ANY_ID,
150 PCI_ANY_ID, 0, 0, 0},
151
152 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6074, PCI_ANY_ID,
153 PCI_ANY_ID, 0, 0, 0},
154 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6078, PCI_ANY_ID,
155 PCI_ANY_ID, 0, 0, 0},
156 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME607F, PCI_ANY_ID,
157 PCI_ANY_ID, 0, 0, 0},
158
159 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6144, PCI_ANY_ID,
160 PCI_ANY_ID, 0, 0, 0},
161 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6148, PCI_ANY_ID,
162 PCI_ANY_ID, 0, 0, 0},
163 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME614F, PCI_ANY_ID,
164 PCI_ANY_ID, 0, 0, 0},
165
166 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6154, PCI_ANY_ID,
167 PCI_ANY_ID, 0, 0, 0},
168 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6158, PCI_ANY_ID,
169 PCI_ANY_ID, 0, 0, 0},
170 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME615F, PCI_ANY_ID,
171 PCI_ANY_ID, 0, 0, 0},
172
173 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6174, PCI_ANY_ID,
174 PCI_ANY_ID, 0, 0, 0},
175 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6178, PCI_ANY_ID,
176 PCI_ANY_ID, 0, 0, 0},
177 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME617F, PCI_ANY_ID,
178 PCI_ANY_ID, 0, 0, 0},
179
180 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6259, PCI_ANY_ID,
181 PCI_ANY_ID, 0, 0, 0},
182
183 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6359, PCI_ANY_ID,
184 PCI_ANY_ID, 0, 0, 0},
185
186 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0630, PCI_ANY_ID,
187 PCI_ANY_ID, 0, 0, 0},
188
189 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8100_A, PCI_ANY_ID,
190 PCI_ANY_ID, 0, 0, 0},
191 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8100_B, PCI_ANY_ID,
192 PCI_ANY_ID, 0, 0, 0},
193
194 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8200_A, PCI_ANY_ID,
195 PCI_ANY_ID, 0, 0, 0},
196 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8200_B, PCI_ANY_ID,
197 PCI_ANY_ID, 0, 0, 0},
198
199 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0940, PCI_ANY_ID,
200 PCI_ANY_ID, 0, 0, 0},
201 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0950, PCI_ANY_ID,
202 PCI_ANY_ID, 0, 0, 0},
203 {PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0960, PCI_ANY_ID,
204 PCI_ANY_ID, 0, 0, 0},
205
206 {0}
207};
208
209MODULE_DEVICE_TABLE(pci, me_pci_table);
210
211/*=============================================================================
212 USB device table.
213 This is used by modprobe to translate USB IDs to drivers.
214 ===========================================================================*/
215/*
216static struct usb_device_id me_usb_table[] __devinitdata = {
217 { USB_DEVICE(USB_VENDOR_ID_MEPHISTO_S1, USB_DEVICE_ID_MEPHISTO_S1) },
218 { 0 }
219};
220
221MODULE_DEVICE_TABLE (usb, me_usb_table);
222*/
223
224/*=============================================================================
225 Templates
226 ===========================================================================*/
227
228#define ME_LOCK_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS) \
229static int CALL(struct file *filep, TYPE *arg){ \
230 int err = 0; \
231 int k = 0; \
232 struct list_head *pos; \
233 me_device_t *device; \
234 TYPE karg; \
235 \
236 PDEBUG("executed.\n"); \
237 \
238 err = copy_from_user(&karg, arg, sizeof(TYPE)); \
239 if(err){ \
240 PERROR("Can't copy arguments to kernel space\n"); \
241 return -EFAULT; \
242 } \
243 \
244 down_read(&me_rwsem); \
245 \
246 list_for_each(pos, &me_device_list){ \
247 if(k == karg.device){ \
248 device = list_entry(pos, me_device_t, list); \
249 break; \
250 } \
251 k++; \
252 } \
253 \
254 if(pos == &me_device_list){ \
255 PERROR("Invalid device number specified\n"); \
256 karg.errno = ME_ERRNO_INVALID_DEVICE; \
257 } \
258 else{ \
259 spin_lock(&me_lock); \
260 if((me_filep != NULL) && (me_filep != filep)){ \
261 spin_unlock(&me_lock); \
262 PERROR("Resource is locked by another process\n"); \
263 if(karg.lock == ME_LOCK_SET) \
264 karg.errno = ME_ERRNO_LOCKED; \
265 else if(karg.lock == ME_LOCK_RELEASE) \
266 karg.errno = ME_ERRNO_SUCCESS; \
267 else{ \
268 PERROR("Invalid lock specified\n"); \
269 karg.errno = ME_ERRNO_INVALID_LOCK; \
270 }\
271 } \
272 else { \
273 me_count++; \
274 spin_unlock(&me_lock); \
275 \
276 karg.errno = device->DEV_CALL ARGS; \
277 \
278 spin_lock(&me_lock); \
279 me_count--; \
280 spin_unlock(&me_lock); \
281 } \
282 } \
283 \
284 up_read(&me_rwsem); \
285 \
286 err = copy_to_user(arg, &karg, sizeof(TYPE)); \
287 if(err){ \
288 PERROR("Can't copy arguments back to user space\n"); \
289 return -EFAULT; \
290 } \
291 \
292 return ME_ERRNO_SUCCESS; \
293}
294
295#define ME_IO_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS) \
296static int CALL(struct file *filep, TYPE *arg){ \
297 int err = 0; \
298 int k = 0; \
299 struct list_head *pos; \
300 me_device_t *device; \
301 TYPE karg; \
302 \
303 PDEBUG("executed.\n"); \
304 \
305 err = copy_from_user(&karg, arg, sizeof(TYPE)); \
306 if(err){ \
307 PERROR("Can't copy arguments to kernel space\n"); \
308 return -EFAULT; \
309 } \
310 \
311 down_read(&me_rwsem); \
312 \
313 list_for_each(pos, &me_device_list){ \
314 if(k == karg.device){ \
315 device = list_entry(pos, me_device_t, list); \
316 break; \
317 } \
318 k++; \
319 } \
320 \
321 if(pos == &me_device_list){ \
322 PERROR("Invalid device number specified\n"); \
323 karg.errno = ME_ERRNO_INVALID_DEVICE; \
324 } \
325 else{ \
326 spin_lock(&me_lock); \
327 if((me_filep != NULL) && (me_filep != filep)){ \
328 spin_unlock(&me_lock); \
329 PERROR("Resource is locked by another process\n"); \
330 karg.errno = ME_ERRNO_LOCKED; \
331 } \
332 else { \
333 me_count++; \
334 spin_unlock(&me_lock); \
335 \
336 karg.errno = device->DEV_CALL ARGS; \
337 \
338 spin_lock(&me_lock); \
339 me_count--; \
340 spin_unlock(&me_lock); \
341 } \
342 } \
343 \
344 up_read(&me_rwsem); \
345 \
346 err = copy_to_user(arg, &karg, sizeof(TYPE)); \
347 if(err){ \
348 PERROR("Can't copy arguments back to user space\n"); \
349 return -EFAULT; \
350 } \
351 \
352 return ME_ERRNO_SUCCESS; \
353}
354
355#define ME_QUERY_MULTIPLEX_STR_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS) \
356static int CALL(struct file *filep, TYPE *arg){ \
357 int err = 0; \
358 int k = 0; \
359 struct list_head *pos; \
360 me_device_t *device; \
361 char *msg = NULL; \
362 TYPE karg; \
363 \
364 PDEBUG("executed.\n"); \
365 \
366 err = copy_from_user(&karg, arg, sizeof(TYPE)); \
367 if(err){ \
368 PERROR("Can't copy arguments to kernel space\n"); \
369 return -EFAULT; \
370 } \
371 \
372 down_read(&me_rwsem); \
373 \
374 list_for_each(pos, &me_device_list){ \
375 if(k == karg.device){ \
376 device = list_entry(pos, me_device_t, list); \
377 break; \
378 } \
379 k++; \
380 } \
381 \
382 if(pos == &me_device_list){ \
383 PERROR("Invalid device number specified\n"); \
384 karg.errno = ME_ERRNO_INVALID_DEVICE; \
385 } \
386 else{ \
387 karg.errno = device->DEV_CALL ARGS; \
388 if(!karg.errno){ \
389 if((strlen(msg) + 1) > karg.count){ \
390 PERROR("User buffer for device name is to little\n"); \
391 karg.errno = ME_ERRNO_USER_BUFFER_SIZE; \
392 } \
393 else{ \
394 err = copy_to_user(karg.name, msg, strlen(msg) + 1); \
395 if(err){ \
396 PERROR("Can't copy device name to user space\n"); \
397 return -EFAULT; \
398 } \
399 } \
400 } \
401 } \
402 \
403 up_read(&me_rwsem); \
404 \
405 err = copy_to_user(arg, &karg, sizeof(TYPE)); \
406 if(err){ \
407 PERROR("Can't copy query back to user space\n"); \
408 return -EFAULT; \
409 } \
410 \
411 return ME_ERRNO_SUCCESS; \
412}
413
414#define ME_QUERY_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS) \
415static int CALL(struct file *filep, TYPE *arg){ \
416 int err = 0; \
417 int k = 0; \
418 struct list_head *pos; \
419 me_device_t *device; \
420 TYPE karg; \
421 \
422 PDEBUG("executed.\n"); \
423 \
424 err = copy_from_user(&karg, arg, sizeof(TYPE)); \
425 if(err){ \
426 PERROR("Can't copy arguments from user space\n"); \
427 return -EFAULT; \
428 } \
429 \
430 down_read(&me_rwsem); \
431 \
432 list_for_each(pos, &me_device_list){ \
433 if(k == karg.device){ \
434 device = list_entry(pos, me_device_t, list); \
435 break; \
436 } \
437 k++; \
438 } \
439 \
440 if(pos == &me_device_list){ \
441 PERROR("Invalid device number specified\n"); \
442 karg.errno = ME_ERRNO_INVALID_DEVICE; \
443 } \
444 else{ \
445 karg.errno = device->DEV_CALL ARGS; \
446 } \
447 \
448 up_read(&me_rwsem); \
449 \
450 err = copy_to_user(arg, &karg, sizeof(TYPE)); \
451 if(err){ \
452 PERROR("Can't copy arguments to user space\n"); \
453 return -EFAULT; \
454 } \
455 \
456 return ME_ERRNO_SUCCESS; \
457}
458
459#endif //__KERNEL__
460#endif
diff --git a/drivers/staging/meilhaus/meplx_reg.h b/drivers/staging/meilhaus/meplx_reg.h
new file mode 100644
index 000000000000..1868614dc232
--- /dev/null
+++ b/drivers/staging/meilhaus/meplx_reg.h
@@ -0,0 +1,53 @@
1/**
2 * @file meplx_reg.h
3 *
4 * @brief PLX 9052 PCI bridge register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _MEPLX_REG_H_
28#define _MEPLX_REG_H_
29
30#ifdef __KERNEL__
31
32#define PLX_INTCSR 0x4C /**< Interrupt control and status register. */
33#define PLX_INTCSR_LOCAL_INT1_EN 0x01 /**< If set, local interrupt 1 is enabled (r/w). */
34#define PLX_INTCSR_LOCAL_INT1_POL 0x02 /**< If set, local interrupt 1 polarity is active high (r/w). */
35#define PLX_INTCSR_LOCAL_INT1_STATE 0x04 /**< If set, local interrupt 1 is active (r/_). */
36#define PLX_INTCSR_LOCAL_INT2_EN 0x08 /**< If set, local interrupt 2 is enabled (r/w). */
37#define PLX_INTCSR_LOCAL_INT2_POL 0x10 /**< If set, local interrupt 2 polarity is active high (r/w). */
38#define PLX_INTCSR_LOCAL_INT2_STATE 0x20 /**< If set, local interrupt 2 is active (r/_). */
39#define PLX_INTCSR_PCI_INT_EN 0x40 /**< If set, PCI interrupt is enabled (r/w). */
40#define PLX_INTCSR_SOFT_INT 0x80 /**< If set, a software interrupt is generated (r/w). */
41
42#define PLX_ICR 0x50 /**< Initialization control register. */
43#define PLX_ICR_BIT_EEPROM_CLOCK_SET 0x01000000
44#define PLX_ICR_BIT_EEPROM_CHIP_SELECT 0x02000000
45#define PLX_ICR_BIT_EEPROM_WRITE 0x04000000
46#define PLX_ICR_BIT_EEPROM_READ 0x08000000
47#define PLX_ICR_BIT_EEPROM_VALID 0x10000000
48
49#define PLX_ICR_MASK_EEPROM 0x1F000000
50#define EEPROM_DELAY 1
51
52#endif
53#endif
diff --git a/drivers/staging/meilhaus/meslist.c b/drivers/staging/meilhaus/meslist.c
new file mode 100644
index 000000000000..7e8b66c05f7e
--- /dev/null
+++ b/drivers/staging/meilhaus/meslist.c
@@ -0,0 +1,173 @@
1/**
2 * @file me_slist.c
3 *
4 * @brief Implements the subdevice list class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#include "meerror.h"
28#include "medefines.h"
29
30#include "meslist.h"
31#include "medebug.h"
32
33int me_slist_query_number_subdevices(struct me_slist *slist, int *number)
34{
35 PDEBUG_LOCKS("called.\n");
36 *number = slist->n;
37 return ME_ERRNO_SUCCESS;
38}
39
40unsigned int me_slist_get_number_subdevices(struct me_slist *slist)
41{
42 PDEBUG_LOCKS("called.\n");
43 return slist->n;
44}
45
46me_subdevice_t *me_slist_get_subdevice(struct me_slist * slist,
47 unsigned int index)
48{
49
50 struct list_head *pos;
51 me_subdevice_t *subdevice = NULL;
52 unsigned int i = 0;
53
54 PDEBUG_LOCKS("called.\n");
55
56 if (index >= slist->n) {
57 PERROR("Index out of range.\n");
58 return NULL;
59 }
60
61 list_for_each(pos, &slist->head) {
62 if (i == index) {
63 subdevice = list_entry(pos, me_subdevice_t, list);
64 break;
65 }
66
67 ++i;
68 }
69
70 return subdevice;
71}
72
73int me_slist_get_subdevice_by_type(struct me_slist *slist,
74 unsigned int start_subdevice,
75 int type, int subtype, int *subdevice)
76{
77 me_subdevice_t *pos;
78 int s_type, s_subtype;
79 unsigned int index = 0;
80
81 PDEBUG_LOCKS("called.\n");
82
83 if (start_subdevice >= slist->n) {
84 PERROR("Start index out of range.\n");
85 return ME_ERRNO_NOMORE_SUBDEVICE_TYPE;
86 }
87
88 list_for_each_entry(pos, &slist->head, list) {
89 if (index < start_subdevice) { // Go forward to start subdevice.
90 ++index;
91 continue;
92 }
93
94 pos->me_subdevice_query_subdevice_type(pos,
95 &s_type, &s_subtype);
96
97 if (subtype == ME_SUBTYPE_ANY) {
98 if (s_type == type)
99 break;
100 } else {
101 if ((s_type == type) && (s_subtype == subtype))
102 break;
103 }
104
105 ++index;
106 }
107
108 if (index >= slist->n) {
109 return ME_ERRNO_NOMORE_SUBDEVICE_TYPE;
110 }
111
112 *subdevice = index;
113
114 return ME_ERRNO_SUCCESS;
115}
116
117void me_slist_add_subdevice_tail(struct me_slist *slist,
118 me_subdevice_t * subdevice)
119{
120 PDEBUG_LOCKS("called.\n");
121
122 list_add_tail(&subdevice->list, &slist->head);
123 ++slist->n;
124}
125
126me_subdevice_t *me_slist_del_subdevice_tail(struct me_slist *slist)
127{
128
129 struct list_head *last;
130 me_subdevice_t *subdevice;
131
132 PDEBUG_LOCKS("called.\n");
133
134 if (list_empty(&slist->head))
135 return NULL;
136
137 last = slist->head.prev;
138
139 subdevice = list_entry(last, me_subdevice_t, list);
140
141 list_del(last);
142
143 --slist->n;
144
145 return subdevice;
146}
147
148int me_slist_init(me_slist_t * slist)
149{
150 PDEBUG_LOCKS("called.\n");
151
152 INIT_LIST_HEAD(&slist->head);
153 slist->n = 0;
154 return 0;
155}
156
157void me_slist_deinit(me_slist_t * slist)
158{
159
160 struct list_head *s;
161 me_subdevice_t *subdevice;
162
163 PDEBUG_LOCKS("called.\n");
164
165 while (!list_empty(&slist->head)) {
166 s = slist->head.next;
167 list_del(s);
168 subdevice = list_entry(s, me_subdevice_t, list);
169 subdevice->me_subdevice_destructor(subdevice);
170 }
171
172 slist->n = 0;
173}
diff --git a/drivers/staging/meilhaus/meslist.h b/drivers/staging/meilhaus/meslist.h
new file mode 100644
index 000000000000..d26c89693d2c
--- /dev/null
+++ b/drivers/staging/meilhaus/meslist.h
@@ -0,0 +1,108 @@
1/**
2 * @file me_slist.h
3 *
4 * @brief Provides the subdevice list class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _ME_SLIST_H_
10#define _ME_SLIST_H_
11
12#include <linux/list.h>
13
14#include "mesubdevice.h"
15
16#ifdef __KERNEL__
17
18/**
19 * @brief The subdevice list container.
20 */
21typedef struct me_slist {
22 struct list_head head; /**< The head of the internal list. */
23 unsigned int n; /**< The number of subdevices in the list. */
24} me_slist_t;
25
26/**
27 * @brief Queries the number of subdevices currently inside the list.
28 *
29 * @param slist The subdevice list to query.
30 * @param[out] number The number of subdevices of the device.
31 *
32 * @return ME-iDS error code.
33 */
34int me_slist_query_number_subdevices(struct me_slist *slist, int *number);
35
36/**
37 * @brief Returns the number of subdevices currently inside the list.
38 *
39 * @param slist The subdevice list to query.
40 *
41 * @return The number of subdevices in the list.
42 */
43unsigned int me_slist_get_number_subdevices(struct me_slist *slist);
44
45/**
46 * @brief Get a subdevice by index.
47 *
48 * @param slist The subdevice list to query.
49 * @param index The index of the subdevice to get in the list.
50 *
51 * @return The subdevice at index if available.\n
52 * NULL if the index is out of range.
53 */
54me_subdevice_t *me_slist_get_subdevice(struct me_slist *slist,
55 unsigned int index);
56
57/**
58 * @brief Get a subdevice index by type and subtype.
59 *
60 * @param slist The subdevice list to query.
61 * @param start_subdevice The subdevice index at which the start shall begin.
62 * @param type The type of the subdevice to query.
63 * @param subtype The subtype of the subdevice to query.
64 * @param[out] subdevice On success this parameter returns the index of the subdevice matching the requested type.
65 *
66 * @return ME_ERRNO_SUCCESS on success.
67 */
68int me_slist_get_subdevice_by_type(struct me_slist *slist,
69 unsigned int start_subdevice,
70 int type, int subtype, int *subdevice);
71
72/**
73 * @brief Adds a subdevice to the tail of the list.
74 *
75 * @param slist The subdevice list to add a subdevice to.
76 * @param subdevice The subdevice to add to the list.
77 */
78void me_slist_add_subdevice_tail(struct me_slist *slist,
79 me_subdevice_t * subdevice);
80
81/**
82 * @brief Removes a subdevice from the tail of the list.
83 *
84 * @param slist The subdevice list.
85 *
86 * @return Pointer to the removed subdeivce.\n
87 * NULL in cases where the list was empty.
88 */
89me_subdevice_t *me_slist_del_subdevice_tail(struct me_slist *slist);
90
91/**
92 * @brief Initializes a subdevice list structure.
93 *
94 * @param lock The subdevice list structure to initialize.
95 * @return 0 on success.
96 */
97int me_slist_init(me_slist_t * slist);
98
99/**
100 * @brief Deinitializes a subdevice list structure and destructs every subdevice in it.
101 *
102 * @param slist The subdevice list structure to deinitialize.
103 * @return 0 on success.
104 */
105void me_slist_deinit(me_slist_t * slist);
106
107#endif
108#endif
diff --git a/drivers/staging/meilhaus/meslock.c b/drivers/staging/meilhaus/meslock.c
new file mode 100644
index 000000000000..5230b89b45b5
--- /dev/null
+++ b/drivers/staging/meilhaus/meslock.c
@@ -0,0 +1,136 @@
1/**
2 * @file meslock.c
3 *
4 * @brief Implements the subdevice lock class.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#include <linux/spinlock.h>
28
29#include "medefines.h"
30#include "meerror.h"
31
32#include "medebug.h"
33#include "meslock.h"
34
35int me_slock_enter(struct me_slock *slock, struct file *filep)
36{
37 PDEBUG_LOCKS("executed.\n");
38
39 spin_lock(&slock->spin_lock);
40
41 if ((slock->filep) != NULL && (slock->filep != filep)) {
42 PERROR("Subdevice is locked by another process.\n");
43 spin_unlock(&slock->spin_lock);
44 return ME_ERRNO_LOCKED;
45 }
46
47 slock->count++;
48
49 spin_unlock(&slock->spin_lock);
50
51 return ME_ERRNO_SUCCESS;
52}
53
54int me_slock_exit(struct me_slock *slock, struct file *filep)
55{
56 PDEBUG_LOCKS("executed.\n");
57
58 spin_lock(&slock->spin_lock);
59 slock->count--;
60 spin_unlock(&slock->spin_lock);
61
62 return ME_ERRNO_SUCCESS;
63}
64
65int me_slock_lock(struct me_slock *slock, struct file *filep, int lock)
66{
67 PDEBUG_LOCKS("executed.\n");
68
69 switch (lock) {
70
71 case ME_LOCK_RELEASE:
72 spin_lock(&slock->spin_lock);
73
74 if (slock->filep == filep)
75 slock->filep = NULL;
76
77 spin_unlock(&slock->spin_lock);
78
79 break;
80
81 case ME_LOCK_SET:
82 spin_lock(&slock->spin_lock);
83
84 if (slock->count) {
85 spin_unlock(&slock->spin_lock);
86 PERROR("Subdevice is used by another process.\n");
87 return ME_ERRNO_USED;
88 } else if (slock->filep == NULL)
89 slock->filep = filep;
90 else if (slock->filep != filep) {
91 spin_unlock(&slock->spin_lock);
92 PERROR("Subdevice is locked by another process.\n");
93 return ME_ERRNO_LOCKED;
94 }
95
96 spin_unlock(&slock->spin_lock);
97
98 break;
99
100 case ME_LOCK_CHECK:
101 spin_lock(&slock->spin_lock);
102
103 if (slock->count) {
104 spin_unlock(&slock->spin_lock);
105 return ME_ERRNO_USED;
106 } else if ((slock->filep != NULL) && (slock->filep != filep)) {
107 spin_unlock(&slock->spin_lock);
108 return ME_ERRNO_LOCKED;
109 }
110
111 spin_unlock(&slock->spin_lock);
112
113 break;
114
115 default:
116 break;
117 }
118
119 return ME_ERRNO_SUCCESS;
120}
121
122void me_slock_deinit(struct me_slock *slock)
123{
124 PDEBUG_LOCKS("executed.\n");
125}
126
127int me_slock_init(me_slock_t * slock)
128{
129 PDEBUG_LOCKS("executed.\n");
130
131 slock->filep = NULL;
132 slock->count = 0;
133 spin_lock_init(&slock->spin_lock);
134
135 return 0;
136}
diff --git a/drivers/staging/meilhaus/meslock.h b/drivers/staging/meilhaus/meslock.h
new file mode 100644
index 000000000000..f42b25c3f622
--- /dev/null
+++ b/drivers/staging/meilhaus/meslock.h
@@ -0,0 +1,73 @@
1/**
2 * @file meslock.h
3 *
4 * @brief Provides the subdevice lock class.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _MESLOCK_H_
10#define _MESLOCK_H_
11
12#include <linux/spinlock.h>
13
14#ifdef __KERNEL__
15
16/**
17 * @brief The subdevice lock class.
18 */
19typedef struct me_slock {
20 struct file *filep; /**< Pointer to file structure holding the subdevice. */
21 int count; /**< Number of tasks which are inside the subdevice. */
22 spinlock_t spin_lock; /**< Spin lock protecting the attributes from concurrent access. */
23} me_slock_t;
24
25/**
26 * @brief Tries to enter a subdevice.
27 *
28 * @param slock The subdevice lock instance.
29 * @param filep The file structure identifying the calling process.
30 *
31 * @return 0 on success.
32 */
33int me_slock_enter(struct me_slock *slock, struct file *filep);
34
35/**
36 * @brief Exits a subdevice.
37 *
38 * @param slock The subdevice lock instance.
39 * @param filep The file structure identifying the calling process.
40 *
41 * @return 0 on success.
42 */
43int me_slock_exit(struct me_slock *slock, struct file *filep);
44
45/**
46 * @brief Tries to perform a locking action on a subdevice.
47 *
48 * @param slock The subdevice lock instance.
49 * @param filep The file structure identifying the calling process.
50 * @param The action to be done.
51 *
52 * @return 0 on success.
53 */
54int me_slock_lock(struct me_slock *slock, struct file *filep, int lock);
55
56/**
57 * @brief Initializes a lock structure.
58 *
59 * @param slock The lock structure to initialize.
60 * @return 0 on success.
61 */
62int me_slock_init(me_slock_t * slock);
63
64/**
65 * @brief Deinitializes a lock structure.
66 *
67 * @param slock The lock structure to deinitialize.
68 * @return 0 on success.
69 */
70void me_slock_deinit(me_slock_t * slock);
71
72#endif
73#endif
diff --git a/drivers/staging/meilhaus/mesubdevice.c b/drivers/staging/meilhaus/mesubdevice.c
new file mode 100644
index 000000000000..98d4f1f7a824
--- /dev/null
+++ b/drivers/staging/meilhaus/mesubdevice.c
@@ -0,0 +1,317 @@
1/**
2 * @file mesubdevice.c
3 *
4 * @brief Subdevice base class implemention.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * This file is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#ifndef __KERNEL__
26# define __KERNEL__
27#endif
28
29#include <linux/slab.h>
30
31#include "medefines.h"
32#include "meerror.h"
33
34#include "medebug.h"
35#include "mesubdevice.h"
36
37static int me_subdevice_io_irq_start(struct me_subdevice *subdevice,
38 struct file *filep,
39 int channel,
40 int irq_source,
41 int irq_edge, int irq_arg, int flags)
42{
43 PDEBUG("executed.\n");
44 return ME_ERRNO_NOT_SUPPORTED;
45}
46
47static int me_subdevice_io_irq_wait(struct me_subdevice *subdevice,
48 struct file *filep,
49 int channel,
50 int *irq_count,
51 int *value, int time_out, int flags)
52{
53 PDEBUG("executed.\n");
54 return ME_ERRNO_NOT_SUPPORTED;
55}
56
57static int me_subdevice_io_irq_stop(struct me_subdevice *subdevice,
58 struct file *filep, int channel, int flags)
59{
60 PDEBUG("executed.\n");
61 return ME_ERRNO_NOT_SUPPORTED;
62}
63
64static int me_subdevice_io_reset_subdevice(struct me_subdevice *subdevice,
65 struct file *filep, int flags)
66{
67 PDEBUG("executed.\n");
68 return ME_ERRNO_NOT_SUPPORTED;
69}
70
71static int me_subdevice_io_single_config(struct me_subdevice *subdevice,
72 struct file *filep,
73 int channel,
74 int single_config,
75 int ref,
76 int trig_chan,
77 int trig_type,
78 int trig_edge, int flags)
79{
80 PDEBUG("executed.\n");
81 return ME_ERRNO_NOT_SUPPORTED;
82}
83
84static int me_subdevice_io_single_read(struct me_subdevice *subdevice,
85 struct file *filep,
86 int channel,
87 int *value, int time_out, int flags)
88{
89 PDEBUG("executed.\n");
90 return ME_ERRNO_NOT_SUPPORTED;
91}
92
93static int me_subdevice_io_single_write(struct me_subdevice *subdevice,
94 struct file *filep,
95 int channel,
96 int value, int time_out, int flags)
97{
98 PDEBUG("executed.\n");
99 return ME_ERRNO_NOT_SUPPORTED;
100}
101
102static int me_subdevice_io_stream_config(struct me_subdevice *subdevice,
103 struct file *filep,
104 meIOStreamConfig_t * config_list,
105 int count,
106 meIOStreamTrigger_t * trigger,
107 int fifo_irq_threshold, int flags)
108{
109 PDEBUG("executed.\n");
110 return ME_ERRNO_NOT_SUPPORTED;
111}
112
113static int me_subdevice_io_stream_new_values(struct me_subdevice *subdevice,
114 struct file *filep,
115 int time_out,
116 int *count, int flags)
117{
118 PDEBUG("executed.\n");
119 return ME_ERRNO_NOT_SUPPORTED;
120}
121
122static int me_subdevice_io_stream_read(struct me_subdevice *subdevice,
123 struct file *filep,
124 int read_mode,
125 int *values, int *count, int flags)
126{
127 PDEBUG("executed.\n");
128 return ME_ERRNO_NOT_SUPPORTED;
129}
130
131static int me_subdevice_io_stream_start(struct me_subdevice *subdevice,
132 struct file *filep,
133 int start_mode, int time_out, int flags)
134{
135 PDEBUG("executed.\n");
136 return ME_ERRNO_NOT_SUPPORTED;
137}
138
139static int me_subdevice_io_stream_status(struct me_subdevice *subdevice,
140 struct file *filep,
141 int wait,
142 int *status, int *count, int flags)
143{
144 PDEBUG("executed.\n");
145 return ME_ERRNO_NOT_SUPPORTED;
146}
147
148static int me_subdevice_io_stream_stop(struct me_subdevice *subdevice,
149 struct file *filep,
150 int stop_mode, int flags)
151{
152 PDEBUG("executed.\n");
153 return ME_ERRNO_NOT_SUPPORTED;
154}
155
156static int me_subdevice_io_stream_write(struct me_subdevice *subdevice,
157 struct file *filep,
158 int write_mode,
159 int *values, int *count, int flags)
160{
161 PDEBUG("executed.\n");
162 return ME_ERRNO_NOT_SUPPORTED;
163}
164
165static int me_subdevice_lock_subdevice(me_subdevice_t * subdevice,
166 struct file *filep, int lock, int flags)
167{
168 PDEBUG("executed.\n");
169 return me_slock_lock(&subdevice->lock, filep, lock);
170}
171
172static int me_subdevice_query_number_channels(struct me_subdevice *subdevice,
173 int *number)
174{
175 PDEBUG("executed.\n");
176 return ME_ERRNO_NOT_SUPPORTED;
177}
178
179static int me_subdevice_query_number_ranges(struct me_subdevice *subdevice,
180 int unit, int *count)
181{
182 PDEBUG("executed.\n");
183 return ME_ERRNO_NOT_SUPPORTED;
184}
185
186static int me_subdevice_query_range_by_min_max(struct me_subdevice *subdevice,
187 int unit,
188 int *min,
189 int *max,
190 int *maxdata, int *range)
191{
192 PDEBUG("executed.\n");
193 return ME_ERRNO_NOT_SUPPORTED;
194}
195
196static int me_subdevice_query_range_info(struct me_subdevice *subdevice,
197 int range,
198 int *unit,
199 int *min, int *max, int *maxdata)
200{
201 PDEBUG("executed.\n");
202 return ME_ERRNO_NOT_SUPPORTED;
203}
204
205static int me_subdevice_query_subdevice_type(struct me_subdevice *subdevice,
206 int *type, int *subtype)
207{
208 PDEBUG("executed.\n");
209 return ME_ERRNO_NOT_SUPPORTED;
210}
211
212static int me_subdevice_query_subdevice_caps(struct me_subdevice *subdevice,
213 int *caps)
214{
215 PDEBUG("executed.\n");
216 *caps = 0;
217 return ME_ERRNO_SUCCESS;
218}
219
220static int me_subdevice_query_subdevice_caps_args(struct me_subdevice
221 *subdevice, int cap,
222 int *args, int count)
223{
224 PDEBUG("executed.\n");
225 return ME_ERRNO_NOT_SUPPORTED;
226}
227
228static int me_subdevice_query_timer(struct me_subdevice *subdevice,
229 int timer,
230 int *base_frequency,
231 long long *min_ticks, long long *max_ticks)
232{
233 PDEBUG("executed.\n");
234 return ME_ERRNO_NOT_SUPPORTED;
235}
236
237static int me_subdevice_config_load(struct me_subdevice *subdevice,
238 me_cfg_device_entry_t * config)
239{
240 PDEBUG("executed.\n");
241 return ME_ERRNO_SUCCESS;
242}
243
244static void me_subdevice_destructor(struct me_subdevice *subdevice)
245{
246 PDEBUG("executed.\n");
247 me_subdevice_deinit(subdevice);
248 kfree(subdevice);
249}
250
251int me_subdevice_init(me_subdevice_t * subdevice)
252{
253 int err;
254
255 PDEBUG("executed.\n");
256
257 /* Init list head */
258 INIT_LIST_HEAD(&subdevice->list);
259
260 /* Initialize the subdevice lock instance */
261
262 err = me_slock_init(&subdevice->lock);
263
264 if (err) {
265 PERROR("Cannot initialize subdevice lock instance.\n");
266 return 1;
267 }
268
269 /* Subdevice base class methods */
270 subdevice->me_subdevice_io_irq_start = me_subdevice_io_irq_start;
271 subdevice->me_subdevice_io_irq_wait = me_subdevice_io_irq_wait;
272 subdevice->me_subdevice_io_irq_stop = me_subdevice_io_irq_stop;
273 subdevice->me_subdevice_io_reset_subdevice =
274 me_subdevice_io_reset_subdevice;
275 subdevice->me_subdevice_io_single_config =
276 me_subdevice_io_single_config;
277 subdevice->me_subdevice_io_single_read = me_subdevice_io_single_read;
278 subdevice->me_subdevice_io_single_write = me_subdevice_io_single_write;
279 subdevice->me_subdevice_io_stream_config =
280 me_subdevice_io_stream_config;
281 subdevice->me_subdevice_io_stream_new_values =
282 me_subdevice_io_stream_new_values;
283 subdevice->me_subdevice_io_stream_read = me_subdevice_io_stream_read;
284 subdevice->me_subdevice_io_stream_start = me_subdevice_io_stream_start;
285 subdevice->me_subdevice_io_stream_status =
286 me_subdevice_io_stream_status;
287 subdevice->me_subdevice_io_stream_stop = me_subdevice_io_stream_stop;
288 subdevice->me_subdevice_io_stream_write = me_subdevice_io_stream_write;
289 subdevice->me_subdevice_lock_subdevice = me_subdevice_lock_subdevice;
290 subdevice->me_subdevice_query_number_channels =
291 me_subdevice_query_number_channels;
292 subdevice->me_subdevice_query_number_ranges =
293 me_subdevice_query_number_ranges;
294 subdevice->me_subdevice_query_range_by_min_max =
295 me_subdevice_query_range_by_min_max;
296 subdevice->me_subdevice_query_range_info =
297 me_subdevice_query_range_info;
298 subdevice->me_subdevice_query_subdevice_type =
299 me_subdevice_query_subdevice_type;
300 subdevice->me_subdevice_query_subdevice_caps =
301 me_subdevice_query_subdevice_caps;
302 subdevice->me_subdevice_query_subdevice_caps_args =
303 me_subdevice_query_subdevice_caps_args;
304 subdevice->me_subdevice_query_timer = me_subdevice_query_timer;
305 subdevice->me_subdevice_config_load = me_subdevice_config_load;
306 subdevice->me_subdevice_destructor = me_subdevice_destructor;
307
308 return 0;
309}
310
311void me_subdevice_deinit(me_subdevice_t * subdevice)
312{
313 PDEBUG("executed.\n");
314 me_subdevice_io_reset_subdevice(subdevice, NULL,
315 ME_IO_RESET_SUBDEVICE_NO_FLAGS);
316 me_slock_deinit(&subdevice->lock);
317}
diff --git a/drivers/staging/meilhaus/mesubdevice.h b/drivers/staging/meilhaus/mesubdevice.h
new file mode 100644
index 000000000000..19ec2b5d96f0
--- /dev/null
+++ b/drivers/staging/meilhaus/mesubdevice.h
@@ -0,0 +1,197 @@
1/**
2 * @file mesubdevice.h
3 *
4 * @brief Provides the subdevice base class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9#ifndef _MESUBDEVICE_H_
10#define _MESUBDEVICE_H_
11
12#include <linux/list.h>
13
14#include "metypes.h"
15#include "meioctl.h"
16#include "meslock.h"
17
18# include <linux/workqueue.h>
19
20#ifdef __KERNEL__
21
22/**
23 * @brief Macro used to enter a subdevice.
24 */
25#define ME_SUBDEVICE_ENTER \
26{ \
27 int err; \
28 err = me_slock_enter(&instance->base.lock, filep); \
29 if(err){ \
30 PERROR("Cannot enter subdevice.\n"); \
31 return err; \
32 } \
33}
34
35/**
36 * @brief Macro used to exit a subdevice.
37 */
38#define ME_SUBDEVICE_EXIT \
39{\
40 int err; \
41 err = me_slock_exit(&instance->base.lock, filep); \
42 if(err){ \
43 PERROR("Cannot exit subdevice.\n"); \
44 return err; \
45 } \
46}
47
48/**
49 * @brief The subdevice base class.
50 */
51typedef struct me_subdevice {
52 /* Attributes */
53 struct list_head list; /**< Enables the subdevice to be added to a dynamic list. */
54 me_slock_t lock; /**< Used by user application in order to lock the subdevice for exclusive usage. */
55
56 /* Methods */
57 int (*me_subdevice_io_irq_start) (struct me_subdevice * subdevice,
58 struct file * filep,
59 int channel,
60 int irq_source,
61 int irq_edge, int irq_arg, int flags);
62
63 int (*me_subdevice_io_irq_wait) (struct me_subdevice * subdevice,
64 struct file * filep,
65 int channel,
66 int *irq_count,
67 int *value, int time_out, int flags);
68
69 int (*me_subdevice_io_irq_stop) (struct me_subdevice * subdevice,
70 struct file * filep,
71 int channel, int flags);
72
73 int (*me_subdevice_io_reset_subdevice) (struct me_subdevice * subdevice,
74 struct file * filep, int flags);
75
76 int (*me_subdevice_io_single_config) (struct me_subdevice * subdevice,
77 struct file * filep,
78 int channel,
79 int single_config,
80 int ref,
81 int trig_chan,
82 int trig_type,
83 int trig_edge, int flags);
84
85 int (*me_subdevice_io_single_read) (struct me_subdevice * subdevice,
86 struct file * filep,
87 int channel,
88 int *value,
89 int time_out, int flags);
90
91 int (*me_subdevice_io_single_write) (struct me_subdevice * subdevice,
92 struct file * filep,
93 int channel,
94 int value,
95 int time_out, int flags);
96
97 int (*me_subdevice_io_stream_config) (struct me_subdevice * subdevice,
98 struct file * filep,
99 meIOStreamConfig_t * config_list,
100 int count,
101 meIOStreamTrigger_t * trigger,
102 int fifo_irq_threshold,
103 int flags);
104
105 int (*me_subdevice_io_stream_new_values) (struct me_subdevice *
106 subdevice,
107 struct file * filep,
108 int time_out, int *count,
109 int flags);
110
111 int (*me_subdevice_io_stream_read) (struct me_subdevice * subdevice,
112 struct file * filep,
113 int read_mode,
114 int *values, int *count, int flags);
115
116 int (*me_subdevice_io_stream_start) (struct me_subdevice * subdevice,
117 struct file * filep,
118 int start_mode,
119 int time_out, int flags);
120
121 int (*me_subdevice_io_stream_status) (struct me_subdevice * subdevice,
122 struct file * filep,
123 int wait,
124 int *status,
125 int *count, int flags);
126
127 int (*me_subdevice_io_stream_stop) (struct me_subdevice * subdevice,
128 struct file * filep,
129 int stop_mode, int flags);
130
131 int (*me_subdevice_io_stream_write) (struct me_subdevice * subdevice,
132 struct file * filep,
133 int write_mode,
134 int *values,
135 int *count, int flags);
136
137 int (*me_subdevice_lock_subdevice) (struct me_subdevice * subdevice,
138 struct file * filep,
139 int lock, int flags);
140
141 int (*me_subdevice_query_number_channels) (struct me_subdevice *
142 subdevice, int *number);
143
144 int (*me_subdevice_query_number_ranges) (struct me_subdevice *
145 subdevice, int unit,
146 int *count);
147
148 int (*me_subdevice_query_range_by_min_max) (struct me_subdevice *
149 subdevice, int unit,
150 int *min, int *max,
151 int *maxdata, int *range);
152
153 int (*me_subdevice_query_range_info) (struct me_subdevice * subdevice,
154 int range,
155 int *unit,
156 int *min, int *max, int *maxdata);
157
158 int (*me_subdevice_query_subdevice_type) (struct me_subdevice *
159 subdevice, int *type,
160 int *subtype);
161
162 int (*me_subdevice_query_subdevice_caps) (struct me_subdevice *
163 subdevice, int *caps);
164
165 int (*me_subdevice_query_subdevice_caps_args) (struct me_subdevice *
166 subdevice, int cap,
167 int *args, int count);
168
169 int (*me_subdevice_query_timer) (struct me_subdevice * subdevice,
170 int timer,
171 int *base_frequency,
172 long long *min_ticks,
173 long long *max_ticks);
174
175 int (*me_subdevice_config_load) (struct me_subdevice * subdevice,
176 me_cfg_device_entry_t * config);
177
178 void (*me_subdevice_destructor) (struct me_subdevice * subdevice);
179} me_subdevice_t;
180
181/**
182 * @brief Initializes a subdevice structure.
183 *
184 * @param subdevice The subdevice structure to initialize.
185 * @return 0 on success.
186 */
187int me_subdevice_init(me_subdevice_t * subdevice);
188
189/**
190 * @brief Deinitializes a subdevice structure.
191 *
192 * @param subdevice The subdevice structure to initialize.
193 */
194void me_subdevice_deinit(me_subdevice_t * subdevice);
195
196#endif
197#endif
diff --git a/drivers/staging/meilhaus/metempl_device.c b/drivers/staging/meilhaus/metempl_device.c
new file mode 100644
index 000000000000..e48632ddc1aa
--- /dev/null
+++ b/drivers/staging/meilhaus/metempl_device.c
@@ -0,0 +1,137 @@
1/**
2 * @file metempl_device.c
3 *
4 * @brief template device class implementation.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef __KERNEL__
28# define __KERNEL__
29#endif
30
31#ifndef MODULE
32# define MODULE
33#endif
34
35#include <linux/module.h>
36
37#include <linux/pci.h>
38#include <linux/slab.h>
39
40#include <meids.h>
41#include "meerror.h"
42#include "mecommon.h"
43#include "meinternal.h"
44
45#include "medebug.h"
46#include "medevice.h"
47#include "metempl_device.h"
48#include "mesubdevice.h"
49#include "metempl_sub.h"
50
51me_device_t *metempl_pci_constructor(struct pci_dev *pci_device)
52{
53 metempl_device_t *metempl_device;
54 me_subdevice_t *subdevice;
55 unsigned int version_idx;
56 int err;
57 int i;
58
59 PDEBUG("executed.\n");
60
61 // Allocate structure for device instance.
62 metempl_device = kmalloc(sizeof(metempl_device_t), GFP_KERNEL);
63
64 if (!metempl_device) {
65 PERROR("Cannot get memory for device instance.\n");
66 return NULL;
67 }
68
69 memset(metempl_device, 0, sizeof(metempl_device_t));
70
71 // Initialize base class structure.
72 err = me_device_pci_init((me_device_t *) metempl_device, pci_device);
73
74 if (err) {
75 kfree(metempl_device);
76 PERROR("Cannot initialize device base class.\n");
77 return NULL;
78 }
79
80 /* Get the index in the device version information table. */
81 version_idx =
82 metempl_versions_get_device_index(metempl_device->base.info.pci.
83 device_id);
84
85 // Initialize spin lock .
86 spin_lock_init(&metempl_device->ctrl_reg_lock);
87
88 // Create subdevice instances.
89 for (i = 0; i < metempl_versions[version_idx].subdevices; i++) {
90 subdevice =
91 (me_subdevice_t *) metempl_sub_constructor(metempl_device->
92 base.info.pci.
93 reg_bases[2], i,
94 &metempl_device->
95 ctrl_reg_lock);
96
97 if (!subdevice) {
98 me_device_deinit((me_device_t *) metempl_device);
99 kfree(metempl_device);
100 PERROR("Cannot get memory for subdevice.\n");
101 return NULL;
102 }
103
104 me_slist_add_subdevice_tail(&metempl_device->base.slist,
105 subdevice);
106 }
107
108 /* Overwrite base class methods if applicable. */
109
110 return (me_device_t *) metempl_device;
111}
112
113// Init and exit of module.
114
115static int __init metempl_init(void)
116{
117 PDEBUG("executed.\n.");
118 return 0;
119}
120
121static void __exit metempl_exit(void)
122{
123 PDEBUG("executed.\n.");
124}
125
126module_init(metempl_init);
127
128module_exit(metempl_exit);
129
130// Administrative stuff for modinfo.
131MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
132MODULE_DESCRIPTION("Device Driver Module for Template Device");
133MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
134MODULE_LICENSE("GPL");
135
136// Export the constructor.
137EXPORT_SYMBOL(metempl_pci_constructor);
diff --git a/drivers/staging/meilhaus/metempl_device.h b/drivers/staging/meilhaus/metempl_device.h
new file mode 100644
index 000000000000..3c3702cc72eb
--- /dev/null
+++ b/drivers/staging/meilhaus/metempl_device.h
@@ -0,0 +1,92 @@
1/**
2 * @file metempl_device.h
3 *
4 * @brief template device class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _METEMPL_DEVICE_H
28#define _METEMPL_DEVICE_H
29
30#include <linux/pci.h>
31#include <linux/spinlock.h>
32
33#include "medevice.h"
34
35#ifdef __KERNEL__
36
37/**
38 * @brief Structure holding template device capabilities.
39 */
40typedef struct metempl_version {
41 uint16_t device_id;
42 unsigned int subdevices;
43} metempl_version_t;
44
45/**
46 * @brief Device capabilities.
47 */
48static metempl_version_t metempl_versions[] = {
49 {0xDEAD, 1},
50 {0},
51};
52
53#define METEMPL_DEVICE_VERSIONS (sizeof(metempl_versions) / sizeof(metempl_version_t) - 1) /**< Returns the number of entries in #metempl_versions. */
54
55/**
56 * @brief Returns the index of the device entry in #metempl_versions.
57 *
58 * @param device_id The PCI device id of the device to query.
59 * @return The index of the device in #metempl_versions.
60 */
61static inline unsigned int metempl_versions_get_device_index(uint16_t device_id)
62{
63 unsigned int i;
64 for (i = 0; i < METEMPL_DEVICE_VERSIONS; i++)
65 if (metempl_versions[i].device_id == device_id)
66 break;
67 return i;
68}
69
70/**
71 * @brief The template device class structure.
72 */
73typedef struct metempl_device {
74 me_device_t base; /**< The Meilhaus device base class. */
75
76 /* Child class attributes. */
77 spinlock_t ctrl_reg_lock;
78} metempl_device_t;
79
80/**
81 * @brief The template device class constructor.
82 *
83 * @param pci_device The pci device structure given by the PCI subsystem.
84 *
85 * @return On succes a new template device instance. \n
86 * NULL on error.
87 */
88me_device_t *metempl_pci_constructor(struct pci_dev *pci_device)
89 __attribute__ ((weak));
90
91#endif
92#endif
diff --git a/drivers/staging/meilhaus/metempl_sub.c b/drivers/staging/meilhaus/metempl_sub.c
new file mode 100644
index 000000000000..f1d65d889e23
--- /dev/null
+++ b/drivers/staging/meilhaus/metempl_sub.c
@@ -0,0 +1,149 @@
1/**
2 * @file metempl_sub.c
3 *
4 * @brief Subdevice instance.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef __KERNEL__
28# define __KERNEL__
29#endif
30
31/*
32 * Includes
33 */
34#include <linux/module.h>
35
36#include <linux/slab.h>
37#include <linux/spinlock.h>
38#include <asm/io.h>
39#include <linux/types.h>
40
41#include "medefines.h"
42#include "meinternal.h"
43#include "meerror.h"
44
45#include "medebug.h"
46#include "metempl_sub_reg.h"
47#include "metempl_sub.h"
48
49/*
50 * Defines
51 */
52
53/*
54 * Functions
55 */
56
57static void metempl_sub_destructor(struct me_subdevice *subdevice)
58{
59 metempl_sub_subdevice_t *instance;
60
61 PDEBUG("executed.\n");
62 instance = (metempl_sub_subdevice_t *) subdevice;
63
64 /* Until there this was the things the default constructor does.
65 If you do not have any additional things to do you can wipe it out. */
66
67 me_subdevice_deinit(&instance->base);
68 kfree(instance);
69}
70
71static int metempl_sub_query_number_channels(me_subdevice_t * subdevice,
72 int *number)
73{
74 PDEBUG("executed.\n");
75 *number = 0;
76 return ME_ERRNO_SUCCESS;
77}
78
79static int metempl_sub_query_subdevice_type(me_subdevice_t * subdevice,
80 int *type, int *subtype)
81{
82 PDEBUG("executed.\n");
83 *type = 0;
84 *subtype = 0;
85 return ME_ERRNO_SUCCESS;
86}
87
88static int metempl_sub_query_subdevice_caps(me_subdevice_t * subdevice,
89 int *caps)
90{
91 PDEBUG("executed.\n");
92 *caps = 0;
93 return ME_ERRNO_SUCCESS;
94}
95
96metempl_sub_subdevice_t *metempl_sub_constructor(uint32_t reg_base,
97 unsigned int sub_idx,
98 spinlock_t * ctrl_reg_lock)
99{
100 metempl_sub_subdevice_t *subdevice;
101 int err;
102
103 PDEBUG("executed.\n");
104
105 /* Allocate memory for subdevice instance */
106 subdevice = kmalloc(sizeof(metempl_sub_subdevice_t), GFP_KERNEL);
107
108 if (!subdevice) {
109 PERROR("Cannot get memory for subdevice instance.\n");
110 return NULL;
111 }
112
113 memset(subdevice, 0, sizeof(metempl_sub_subdevice_t));
114
115 /* Check if subdevice index is out of range */
116
117 if (sub_idx >= 2) {
118 PERROR("Template subdevice index is out of range.\n");
119 kfree(subdevice);
120 return NULL;
121 }
122
123 /* Initialize subdevice base class */
124 err = me_subdevice_init(&subdevice->base);
125
126 if (err) {
127 PERROR("Cannot initialize subdevice base class instance.\n");
128 kfree(subdevice);
129 return NULL;
130 }
131 // Initialize spin locks.
132 spin_lock_init(&subdevice->subdevice_lock);
133
134 subdevice->ctrl_reg_lock = ctrl_reg_lock;
135
136 /* Save the subdevice index */
137 subdevice->sub_idx = sub_idx;
138
139 /* Override base class methods. */
140 subdevice->base.me_subdevice_destructor = metempl_sub_destructor;
141 subdevice->base.me_subdevice_query_number_channels =
142 metempl_sub_query_number_channels;
143 subdevice->base.me_subdevice_query_subdevice_type =
144 metempl_sub_query_subdevice_type;
145 subdevice->base.me_subdevice_query_subdevice_caps =
146 metempl_sub_query_subdevice_caps;
147
148 return subdevice;
149}
diff --git a/drivers/staging/meilhaus/metempl_sub.h b/drivers/staging/meilhaus/metempl_sub.h
new file mode 100644
index 000000000000..80c8af9a8c5a
--- /dev/null
+++ b/drivers/staging/meilhaus/metempl_sub.h
@@ -0,0 +1,64 @@
1/**
2 * @file metempl_sub.h
3 *
4 * @brief Meilhaus subdevice class.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _METEMPL_SUB_H_
28#define _METEMPL_SUB_H_
29
30#include "mesubdevice.h"
31
32#ifdef __KERNEL__
33
34/**
35 * @brief The subdevice class.
36 */
37typedef struct metempl_sub_subdevice {
38 /* Inheritance */
39 me_subdevice_t base; /**< The subdevice base class. */
40
41 /* Attributes */
42 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
43 spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
44 int sub_idx; /**< The index of the subdevice on the device. */
45
46 unsigned long ctrl_reg; /**< Register to configure the modes. */
47} metempl_sub_subdevice_t;
48
49/**
50 * @brief The constructor to generate a subdevice instance.
51 *
52 * @param reg_base The register base address of the device as returned by the PCI BIOS.
53 * @param sub_idx The index of the subdevice on the device.
54 * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
55 *
56 * @return Pointer to new instance on success.\n
57 * NULL on error.
58 */
59metempl_sub_subdevice_t *metempl_sub_constructor(uint32_t reg_base,
60 unsigned int sub_idx,
61 spinlock_t * ctrl_reg_lock);
62
63#endif
64#endif
diff --git a/drivers/staging/meilhaus/metempl_sub_reg.h b/drivers/staging/meilhaus/metempl_sub_reg.h
new file mode 100644
index 000000000000..1a2cab778a12
--- /dev/null
+++ b/drivers/staging/meilhaus/metempl_sub_reg.h
@@ -0,0 +1,35 @@
1/**
2 * @file metempl_sub_reg.h
3 *
4 * @brief Subdevice register definitions.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9/*
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef _METEMPL_SUB_REG_H_
28#define _METEMPL_SUB_REG_H_
29
30#ifdef __KERNEL__
31
32#define METEMPL_PORT_MODE 0x0010 /**< Configuration register. */
33
34#endif
35#endif
diff --git a/drivers/staging/meilhaus/metypes.h b/drivers/staging/meilhaus/metypes.h
new file mode 100644
index 000000000000..228ea15753ea
--- /dev/null
+++ b/drivers/staging/meilhaus/metypes.h
@@ -0,0 +1,95 @@
1/*
2 * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3 *
4 * Source File : metypes.h
5 * Author : GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
6 */
7
8#ifndef _METYPES_H_
9#define _METYPES_H_
10
11
12typedef int (*meErrorCB_t)(char *pcFunctionName, int iErrorCode);
13
14typedef int (*meIOStreamCB_t)(
15 int iDevice,
16 int iSubdevice,
17 int iCount,
18 void *pvContext,
19 int iErrorCode);
20
21typedef int (*meIOIrqCB_t)(
22 int iDevice,
23 int iSubdevice,
24 int iChannel,
25 int iIrqCount,
26 int iValue,
27 void *pvContext,
28 int iErrorCode);
29
30
31typedef struct meIOSingle {
32 int iDevice;
33 int iSubdevice;
34 int iChannel;
35 int iDir;
36 int iValue;
37 int iTimeOut;
38 int iFlags;
39 int iErrno;
40} meIOSingle_t;
41
42
43typedef struct meIOStreamConfig {
44 int iChannel;
45 int iStreamConfig;
46 int iRef;
47 int iFlags;
48} meIOStreamConfig_t;
49
50
51typedef struct meIOStreamTrigger {
52 int iAcqStartTrigType;
53 int iAcqStartTrigEdge;
54 int iAcqStartTrigChan;
55 int iAcqStartTicksLow;
56 int iAcqStartTicksHigh;
57 int iAcqStartArgs[10];
58 int iScanStartTrigType;
59 int iScanStartTicksLow;
60 int iScanStartTicksHigh;
61 int iScanStartArgs[10];
62 int iConvStartTrigType;
63 int iConvStartTicksLow;
64 int iConvStartTicksHigh;
65 int iConvStartArgs[10];
66 int iScanStopTrigType;
67 int iScanStopCount;
68 int iScanStopArgs[10];
69 int iAcqStopTrigType;
70 int iAcqStopCount;
71 int iAcqStopArgs[10];
72 int iFlags;
73} meIOStreamTrigger_t;
74
75
76typedef struct meIOStreamStart {
77 int iDevice;
78 int iSubdevice;
79 int iStartMode;
80 int iTimeOut;
81 int iFlags;
82 int iErrno;
83} meIOStreamStart_t;
84
85
86typedef struct meIOStreamStop {
87 int iDevice;
88 int iSubdevice;
89 int iStopMode;
90 int iFlags;
91 int iErrno;
92} meIOStreamStop_t;
93
94
95#endif