[PATCH 637/641] Staging: meilhaus: remove the drivers
Greg Kroah-Hartman
gregkh at suse.de
Tue Sep 15 12:14:28 PDT 2009
The comedi drivers should be used instead, no need to have
these in here as well.
Cc: David Kiliani <mail at davidkiliani.de>
Cc: Meilhaus Support <support at meilhaus.de>
Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
---
drivers/staging/Kconfig | 2 -
drivers/staging/Makefile | 1 -
drivers/staging/meilhaus/Kconfig | 128 -
drivers/staging/meilhaus/Makefile | 43 -
drivers/staging/meilhaus/TODO | 10 -
drivers/staging/meilhaus/me0600_device.c | 213 -
drivers/staging/meilhaus/me0600_device.h | 97 -
drivers/staging/meilhaus/me0600_dio.c | 415 --
drivers/staging/meilhaus/me0600_dio.h | 68 -
drivers/staging/meilhaus/me0600_dio_reg.h | 41 -
drivers/staging/meilhaus/me0600_ext_irq.c | 469 --
drivers/staging/meilhaus/me0600_ext_irq.h | 58 -
drivers/staging/meilhaus/me0600_ext_irq_reg.h | 18 -
drivers/staging/meilhaus/me0600_optoi.c | 243 -
drivers/staging/meilhaus/me0600_optoi.h | 58 -
drivers/staging/meilhaus/me0600_optoi_reg.h | 35 -
drivers/staging/meilhaus/me0600_relay.c | 359 --
drivers/staging/meilhaus/me0600_relay.h | 63 -
drivers/staging/meilhaus/me0600_relay_reg.h | 36 -
drivers/staging/meilhaus/me0600_ttli.c | 238 -
drivers/staging/meilhaus/me0600_ttli.h | 58 -
drivers/staging/meilhaus/me0600_ttli_reg.h | 35 -
drivers/staging/meilhaus/me0900_device.c | 178 -
drivers/staging/meilhaus/me0900_device.h | 92 -
drivers/staging/meilhaus/me0900_di.c | 245 -
drivers/staging/meilhaus/me0900_di.h | 65 -
drivers/staging/meilhaus/me0900_do.c | 314 --
drivers/staging/meilhaus/me0900_do.h | 68 -
drivers/staging/meilhaus/me0900_reg.h | 40 -
drivers/staging/meilhaus/me1000_device.c | 206 -
drivers/staging/meilhaus/me1000_device.h | 59 -
drivers/staging/meilhaus/me1000_dio.c | 438 --
drivers/staging/meilhaus/me1000_dio.h | 71 -
drivers/staging/meilhaus/me1000_dio_reg.h | 50 -
drivers/staging/meilhaus/me1400_device.c | 253 --
drivers/staging/meilhaus/me1400_device.h | 108 -
drivers/staging/meilhaus/me1400_ext_irq.c | 507 ---
drivers/staging/meilhaus/me1400_ext_irq.h | 62 -
drivers/staging/meilhaus/me1400_ext_irq_reg.h | 56 -
drivers/staging/meilhaus/me1600_ao.c | 1017 -----
drivers/staging/meilhaus/me1600_ao.h | 128 -
drivers/staging/meilhaus/me1600_ao_reg.h | 66 -
drivers/staging/meilhaus/me1600_device.c | 259 --
drivers/staging/meilhaus/me1600_device.h | 101 -
drivers/staging/meilhaus/me4600_ai.c | 3405 --------------
drivers/staging/meilhaus/me4600_ai.h | 175 -
drivers/staging/meilhaus/me4600_ai_reg.h | 107 -
drivers/staging/meilhaus/me4600_ao.c | 5974 -------------------------
drivers/staging/meilhaus/me4600_ao.h | 259 --
drivers/staging/meilhaus/me4600_ao_reg.h | 113 -
drivers/staging/meilhaus/me4600_device.c | 371 --
drivers/staging/meilhaus/me4600_device.h | 151 -
drivers/staging/meilhaus/me4600_di.c | 256 --
drivers/staging/meilhaus/me4600_di.h | 64 -
drivers/staging/meilhaus/me4600_dio.c | 510 ---
drivers/staging/meilhaus/me4600_dio.h | 69 -
drivers/staging/meilhaus/me4600_dio_reg.h | 63 -
drivers/staging/meilhaus/me4600_do.c | 433 --
drivers/staging/meilhaus/me4600_do.h | 65 -
drivers/staging/meilhaus/me4600_ext_irq.c | 457 --
drivers/staging/meilhaus/me4600_ext_irq.h | 78 -
drivers/staging/meilhaus/me4600_ext_irq_reg.h | 41 -
drivers/staging/meilhaus/me4600_reg.h | 46 -
drivers/staging/meilhaus/me6000_ao.c | 3709 ---------------
drivers/staging/meilhaus/me6000_ao.h | 195 -
drivers/staging/meilhaus/me6000_ao_reg.h | 177 -
drivers/staging/meilhaus/me6000_device.c | 209 -
drivers/staging/meilhaus/me6000_device.h | 149 -
drivers/staging/meilhaus/me6000_dio.c | 415 --
drivers/staging/meilhaus/me6000_dio.h | 68 -
drivers/staging/meilhaus/me6000_dio_reg.h | 43 -
drivers/staging/meilhaus/me6000_reg.h | 35 -
drivers/staging/meilhaus/me8100_device.c | 185 -
drivers/staging/meilhaus/me8100_device.h | 97 -
drivers/staging/meilhaus/me8100_di.c | 684 ---
drivers/staging/meilhaus/me8100_di.h | 89 -
drivers/staging/meilhaus/me8100_di_reg.h | 47 -
drivers/staging/meilhaus/me8100_do.c | 391 --
drivers/staging/meilhaus/me8100_do.h | 70 -
drivers/staging/meilhaus/me8100_do_reg.h | 36 -
drivers/staging/meilhaus/me8100_reg.h | 41 -
drivers/staging/meilhaus/me8200_device.c | 192 -
drivers/staging/meilhaus/me8200_device.h | 97 -
drivers/staging/meilhaus/me8200_di.c | 832 ----
drivers/staging/meilhaus/me8200_di.h | 92 -
drivers/staging/meilhaus/me8200_di_reg.h | 75 -
drivers/staging/meilhaus/me8200_dio.c | 418 --
drivers/staging/meilhaus/me8200_dio.h | 68 -
drivers/staging/meilhaus/me8200_dio_reg.h | 43 -
drivers/staging/meilhaus/me8200_do.c | 591 ---
drivers/staging/meilhaus/me8200_do.h | 75 -
drivers/staging/meilhaus/me8200_do_reg.h | 40 -
drivers/staging/meilhaus/me8200_reg.h | 46 -
drivers/staging/meilhaus/me8254.c | 1176 -----
drivers/staging/meilhaus/me8254.h | 80 -
drivers/staging/meilhaus/me8254_reg.h | 172 -
drivers/staging/meilhaus/me8255.c | 462 --
drivers/staging/meilhaus/me8255.h | 59 -
drivers/staging/meilhaus/me8255_reg.h | 50 -
drivers/staging/meilhaus/mecirc_buf.h | 131 -
drivers/staging/meilhaus/mecommon.h | 26 -
drivers/staging/meilhaus/medebug.h | 125 -
drivers/staging/meilhaus/medefines.h | 449 --
drivers/staging/meilhaus/medevice.c | 1740 -------
drivers/staging/meilhaus/medevice.h | 304 --
drivers/staging/meilhaus/medlist.c | 127 -
drivers/staging/meilhaus/medlist.h | 91 -
drivers/staging/meilhaus/medlock.c | 195 -
drivers/staging/meilhaus/medlock.h | 76 -
drivers/staging/meilhaus/medriver.h | 350 --
drivers/staging/meilhaus/medummy.c | 1264 ------
drivers/staging/meilhaus/medummy.h | 40 -
drivers/staging/meilhaus/meerror.h | 100 -
drivers/staging/meilhaus/mefirmware.c | 137 -
drivers/staging/meilhaus/mefirmware.h | 57 -
drivers/staging/meilhaus/meids.h | 31 -
drivers/staging/meilhaus/meinternal.h | 363 --
drivers/staging/meilhaus/meioctl.h | 515 ---
drivers/staging/meilhaus/memain.c | 2084 ---------
drivers/staging/meilhaus/memain.h | 266 --
drivers/staging/meilhaus/meplx_reg.h | 53 -
drivers/staging/meilhaus/meslist.c | 173 -
drivers/staging/meilhaus/meslist.h | 108 -
drivers/staging/meilhaus/meslock.c | 136 -
drivers/staging/meilhaus/meslock.h | 73 -
drivers/staging/meilhaus/mesubdevice.c | 317 --
drivers/staging/meilhaus/mesubdevice.h | 197 -
drivers/staging/meilhaus/metempl_device.c | 135 -
drivers/staging/meilhaus/metempl_device.h | 92 -
drivers/staging/meilhaus/metempl_sub.c | 149 -
drivers/staging/meilhaus/metempl_sub.h | 64 -
drivers/staging/meilhaus/metempl_sub_reg.h | 35 -
drivers/staging/meilhaus/metypes.h | 95 -
133 files changed, 0 insertions(+), 41014 deletions(-)
delete mode 100644 drivers/staging/meilhaus/Kconfig
delete mode 100644 drivers/staging/meilhaus/Makefile
delete mode 100644 drivers/staging/meilhaus/TODO
delete mode 100644 drivers/staging/meilhaus/me0600_device.c
delete mode 100644 drivers/staging/meilhaus/me0600_device.h
delete mode 100644 drivers/staging/meilhaus/me0600_dio.c
delete mode 100644 drivers/staging/meilhaus/me0600_dio.h
delete mode 100644 drivers/staging/meilhaus/me0600_dio_reg.h
delete mode 100644 drivers/staging/meilhaus/me0600_ext_irq.c
delete mode 100644 drivers/staging/meilhaus/me0600_ext_irq.h
delete mode 100644 drivers/staging/meilhaus/me0600_ext_irq_reg.h
delete mode 100644 drivers/staging/meilhaus/me0600_optoi.c
delete mode 100644 drivers/staging/meilhaus/me0600_optoi.h
delete mode 100644 drivers/staging/meilhaus/me0600_optoi_reg.h
delete mode 100644 drivers/staging/meilhaus/me0600_relay.c
delete mode 100644 drivers/staging/meilhaus/me0600_relay.h
delete mode 100644 drivers/staging/meilhaus/me0600_relay_reg.h
delete mode 100644 drivers/staging/meilhaus/me0600_ttli.c
delete mode 100644 drivers/staging/meilhaus/me0600_ttli.h
delete mode 100644 drivers/staging/meilhaus/me0600_ttli_reg.h
delete mode 100644 drivers/staging/meilhaus/me0900_device.c
delete mode 100644 drivers/staging/meilhaus/me0900_device.h
delete mode 100644 drivers/staging/meilhaus/me0900_di.c
delete mode 100644 drivers/staging/meilhaus/me0900_di.h
delete mode 100644 drivers/staging/meilhaus/me0900_do.c
delete mode 100644 drivers/staging/meilhaus/me0900_do.h
delete mode 100644 drivers/staging/meilhaus/me0900_reg.h
delete mode 100644 drivers/staging/meilhaus/me1000_device.c
delete mode 100644 drivers/staging/meilhaus/me1000_device.h
delete mode 100644 drivers/staging/meilhaus/me1000_dio.c
delete mode 100644 drivers/staging/meilhaus/me1000_dio.h
delete mode 100644 drivers/staging/meilhaus/me1000_dio_reg.h
delete mode 100644 drivers/staging/meilhaus/me1400_device.c
delete mode 100644 drivers/staging/meilhaus/me1400_device.h
delete mode 100644 drivers/staging/meilhaus/me1400_ext_irq.c
delete mode 100644 drivers/staging/meilhaus/me1400_ext_irq.h
delete mode 100644 drivers/staging/meilhaus/me1400_ext_irq_reg.h
delete mode 100644 drivers/staging/meilhaus/me1600_ao.c
delete mode 100644 drivers/staging/meilhaus/me1600_ao.h
delete mode 100644 drivers/staging/meilhaus/me1600_ao_reg.h
delete mode 100644 drivers/staging/meilhaus/me1600_device.c
delete mode 100644 drivers/staging/meilhaus/me1600_device.h
delete mode 100644 drivers/staging/meilhaus/me4600_ai.c
delete mode 100644 drivers/staging/meilhaus/me4600_ai.h
delete mode 100644 drivers/staging/meilhaus/me4600_ai_reg.h
delete mode 100644 drivers/staging/meilhaus/me4600_ao.c
delete mode 100644 drivers/staging/meilhaus/me4600_ao.h
delete mode 100644 drivers/staging/meilhaus/me4600_ao_reg.h
delete mode 100644 drivers/staging/meilhaus/me4600_device.c
delete mode 100644 drivers/staging/meilhaus/me4600_device.h
delete mode 100644 drivers/staging/meilhaus/me4600_di.c
delete mode 100644 drivers/staging/meilhaus/me4600_di.h
delete mode 100644 drivers/staging/meilhaus/me4600_dio.c
delete mode 100644 drivers/staging/meilhaus/me4600_dio.h
delete mode 100644 drivers/staging/meilhaus/me4600_dio_reg.h
delete mode 100644 drivers/staging/meilhaus/me4600_do.c
delete mode 100644 drivers/staging/meilhaus/me4600_do.h
delete mode 100644 drivers/staging/meilhaus/me4600_ext_irq.c
delete mode 100644 drivers/staging/meilhaus/me4600_ext_irq.h
delete mode 100644 drivers/staging/meilhaus/me4600_ext_irq_reg.h
delete mode 100644 drivers/staging/meilhaus/me4600_reg.h
delete mode 100644 drivers/staging/meilhaus/me6000_ao.c
delete mode 100644 drivers/staging/meilhaus/me6000_ao.h
delete mode 100644 drivers/staging/meilhaus/me6000_ao_reg.h
delete mode 100644 drivers/staging/meilhaus/me6000_device.c
delete mode 100644 drivers/staging/meilhaus/me6000_device.h
delete mode 100644 drivers/staging/meilhaus/me6000_dio.c
delete mode 100644 drivers/staging/meilhaus/me6000_dio.h
delete mode 100644 drivers/staging/meilhaus/me6000_dio_reg.h
delete mode 100644 drivers/staging/meilhaus/me6000_reg.h
delete mode 100644 drivers/staging/meilhaus/me8100_device.c
delete mode 100644 drivers/staging/meilhaus/me8100_device.h
delete mode 100644 drivers/staging/meilhaus/me8100_di.c
delete mode 100644 drivers/staging/meilhaus/me8100_di.h
delete mode 100644 drivers/staging/meilhaus/me8100_di_reg.h
delete mode 100644 drivers/staging/meilhaus/me8100_do.c
delete mode 100644 drivers/staging/meilhaus/me8100_do.h
delete mode 100644 drivers/staging/meilhaus/me8100_do_reg.h
delete mode 100644 drivers/staging/meilhaus/me8100_reg.h
delete mode 100644 drivers/staging/meilhaus/me8200_device.c
delete mode 100644 drivers/staging/meilhaus/me8200_device.h
delete mode 100644 drivers/staging/meilhaus/me8200_di.c
delete mode 100644 drivers/staging/meilhaus/me8200_di.h
delete mode 100644 drivers/staging/meilhaus/me8200_di_reg.h
delete mode 100644 drivers/staging/meilhaus/me8200_dio.c
delete mode 100644 drivers/staging/meilhaus/me8200_dio.h
delete mode 100644 drivers/staging/meilhaus/me8200_dio_reg.h
delete mode 100644 drivers/staging/meilhaus/me8200_do.c
delete mode 100644 drivers/staging/meilhaus/me8200_do.h
delete mode 100644 drivers/staging/meilhaus/me8200_do_reg.h
delete mode 100644 drivers/staging/meilhaus/me8200_reg.h
delete mode 100644 drivers/staging/meilhaus/me8254.c
delete mode 100644 drivers/staging/meilhaus/me8254.h
delete mode 100644 drivers/staging/meilhaus/me8254_reg.h
delete mode 100644 drivers/staging/meilhaus/me8255.c
delete mode 100644 drivers/staging/meilhaus/me8255.h
delete mode 100644 drivers/staging/meilhaus/me8255_reg.h
delete mode 100644 drivers/staging/meilhaus/mecirc_buf.h
delete mode 100644 drivers/staging/meilhaus/mecommon.h
delete mode 100644 drivers/staging/meilhaus/medebug.h
delete mode 100644 drivers/staging/meilhaus/medefines.h
delete mode 100644 drivers/staging/meilhaus/medevice.c
delete mode 100644 drivers/staging/meilhaus/medevice.h
delete mode 100644 drivers/staging/meilhaus/medlist.c
delete mode 100644 drivers/staging/meilhaus/medlist.h
delete mode 100644 drivers/staging/meilhaus/medlock.c
delete mode 100644 drivers/staging/meilhaus/medlock.h
delete mode 100644 drivers/staging/meilhaus/medriver.h
delete mode 100644 drivers/staging/meilhaus/medummy.c
delete mode 100644 drivers/staging/meilhaus/medummy.h
delete mode 100644 drivers/staging/meilhaus/meerror.h
delete mode 100644 drivers/staging/meilhaus/mefirmware.c
delete mode 100644 drivers/staging/meilhaus/mefirmware.h
delete mode 100644 drivers/staging/meilhaus/meids.h
delete mode 100644 drivers/staging/meilhaus/meinternal.h
delete mode 100644 drivers/staging/meilhaus/meioctl.h
delete mode 100644 drivers/staging/meilhaus/memain.c
delete mode 100644 drivers/staging/meilhaus/memain.h
delete mode 100644 drivers/staging/meilhaus/meplx_reg.h
delete mode 100644 drivers/staging/meilhaus/meslist.c
delete mode 100644 drivers/staging/meilhaus/meslist.h
delete mode 100644 drivers/staging/meilhaus/meslock.c
delete mode 100644 drivers/staging/meilhaus/meslock.h
delete mode 100644 drivers/staging/meilhaus/mesubdevice.c
delete mode 100644 drivers/staging/meilhaus/mesubdevice.h
delete mode 100644 drivers/staging/meilhaus/metempl_device.c
delete mode 100644 drivers/staging/meilhaus/metempl_device.h
delete mode 100644 drivers/staging/meilhaus/metempl_sub.c
delete mode 100644 drivers/staging/meilhaus/metempl_sub.h
delete mode 100644 drivers/staging/meilhaus/metempl_sub_reg.h
delete mode 100644 drivers/staging/meilhaus/metypes.h
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index d76f6b3..982e944 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -47,8 +47,6 @@ source "drivers/staging/slicoss/Kconfig"
source "drivers/staging/sxg/Kconfig"
-source "drivers/staging/meilhaus/Kconfig"
-
source "drivers/staging/go7007/Kconfig"
source "drivers/staging/usbip/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 01bf228..4eabb44 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -6,7 +6,6 @@ obj-$(CONFIG_STAGING) += staging.o
obj-$(CONFIG_ET131X) += et131x/
obj-$(CONFIG_SLICOSS) += slicoss/
obj-$(CONFIG_SXG) += sxg/
-obj-$(CONFIG_MEILHAUS) += meilhaus/
obj-$(CONFIG_VIDEO_GO7007) += go7007/
obj-$(CONFIG_USB_IP_COMMON) += usbip/
obj-$(CONFIG_W35UND) += winbond/
diff --git a/drivers/staging/meilhaus/Kconfig b/drivers/staging/meilhaus/Kconfig
deleted file mode 100644
index 923af22..0000000
--- a/drivers/staging/meilhaus/Kconfig
+++ /dev/null
@@ -1,128 +0,0 @@
-#
-# Meilhaus configuration
-#
-
-menuconfig MEILHAUS
- tristate "Meilhaus support"
- depends on m
- ---help---
- If you have a Meilhaus card, say Y (or M) here.
-
- You need both this driver, and the driver for the particular
- data collection card.
-
- To compile this driver as a module, choose M here. The module will
- be called memain.
-
-if MEILHAUS
-
-config ME0600
- tristate "Meilhaus ME-600 support"
- default n
- depends on PCI && m
- help
- This driver supports the Meilhaus ME-600 family of boards
- that do data collection and multipurpose I/O.
-
- To compile this driver as a module, choose M here: the module
- will be called me0600.
-
-config ME0900
- tristate "Meilhaus ME-900 support"
- default n
- depends on PCI && m
- help
- This driver supports the Meilhaus ME-900 family of boards
- that do data collection and multipurpose I/O.
-
- To compile this driver as a module, choose M here: the module
- will be called me0900.
-
-config ME1000
- tristate "Meilhaus ME-1000 support"
- default n
- depends on PCI && m
- help
- This driver supports the Meilhaus ME-1000 family of boards
- that do data collection and multipurpose I/O.
-
- To compile this driver as a module, choose M here: the module
- will be called me1000.
-
-config ME1400
- tristate "Meilhaus ME-1400 support"
- default n
- depends on PCI && m
- help
- This driver supports the Meilhaus ME-1400 family of boards
- that do data collection and multipurpose I/O.
-
- To compile this driver as a module, choose M here: the module
- will be called me1400.
-
-config ME1600
- tristate "Meilhaus ME-1600 support"
- default n
- depends on PCI && m
- help
- This driver supports the Meilhaus ME-1600 family of boards
- that do data collection and multipurpose I/O.
-
- To compile this driver as a module, choose M here: the module
- will be called me1600.
-
-config ME4600
- tristate "Meilhaus ME-4600 support"
- default n
- depends on PCI && m
- help
- This driver supports the Meilhaus ME-4600 family of boards
- that do data collection and multipurpose I/O.
-
- To compile this driver as a module, choose M here: the module
- will be called me4600.
-
-config ME6000
- tristate "Meilhaus ME-6000 support"
- default n
- depends on PCI && m
- help
- This driver supports the Meilhaus ME-6000 family of boards
- that do data collection and multipurpose I/O.
-
- To compile this driver as a module, choose M here: the module
- will be called me6000.
-
-config ME8100
- tristate "Meilhaus ME-8100 support"
- default n
- depends on PCI && m
- help
- This driver supports the Meilhaus ME-8100 family of boards
- that do data collection and multipurpose I/O.
-
- To compile this driver as a module, choose M here: the module
- will be called me8100.
-
-config ME8200
- tristate "Meilhaus ME-8200 support"
- default n
- depends on PCI && m
- help
- This driver supports the Meilhaus ME-8200 family of boards
- that do data collection and multipurpose I/O.
-
- To compile this driver as a module, choose M here: the module
- will be called me8200.
-
-config MEDUMMY
- tristate "Meilhaus dummy driver"
- default n
- depends on PCI && m
- help
- This provides a dummy driver for the Meilhaus driver package
-
- To compile this driver as a module, choose M here: the module
- will be called medummy.
-
-endif # MEILHAUS
diff --git a/drivers/staging/meilhaus/Makefile b/drivers/staging/meilhaus/Makefile
deleted file mode 100644
index 5ab2c1c..0000000
--- a/drivers/staging/meilhaus/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Makefile for Meilhaus linux driver system
-#
-
-obj-$(CONFIG_MEILHAUS) += memain.o
-obj-$(CONFIG_ME1600) += me1600.o
-obj-$(CONFIG_ME1000) += me1000.o
-obj-$(CONFIG_ME1400) += me1400.o
-obj-$(CONFIG_ME4600) += me4600.o
-obj-$(CONFIG_ME6000) += me6000.o
-obj-$(CONFIG_ME0600) += me0600.o
-obj-$(CONFIG_ME8100) += me8100.o
-obj-$(CONFIG_ME8200) += me8200.o
-obj-$(CONFIG_ME0900) += me0900.o
-obj-$(CONFIG_MEDUMMY) += medummy.o
-
-
-me1600-objs := medevice.o medlist.o medlock.o me1600_device.o
-me1600-objs += mesubdevice.o meslist.o meslock.o me1600_ao.o
-
-me1000-objs := medevice.o medlist.o medlock.o me1000_device.o
-me1000-objs += mesubdevice.o meslist.o meslock.o me1000_dio.o
-
-me1400-objs := medevice.o medlist.o medlock.o me1400_device.o
-me1400-objs += mesubdevice.o meslist.o meslock.o me8254.o me8255.o me1400_ext_irq.o
-
-me4600-objs := medevice.o medlist.o medlock.o mefirmware.o me4600_device.o
-me4600-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
-
-me6000-objs := medevice.o medlist.o medlock.o mefirmware.o me6000_device.o
-me6000-objs += mesubdevice.o meslist.o meslock.o me6000_dio.o me6000_ao.o
-
-me0600-objs := medevice.o medlist.o medlock.o me0600_device.o
-me0600-objs += mesubdevice.o meslist.o meslock.o me0600_relay.o me0600_ttli.o me0600_optoi.o me0600_dio.o me0600_ext_irq.o
-
-me8100-objs := medevice.o medlist.o medlock.o me8100_device.o
-me8100-objs += mesubdevice.o meslist.o meslock.o me8100_di.o me8100_do.o me8254.o
-
-me8200-objs := medevice.o medlist.o medlock.o me8200_device.o
-me8200-objs += mesubdevice.o meslist.o meslock.o me8200_di.o me8200_do.o me8200_dio.o
-
-me0900-objs := medevice.o medlist.o medlock.o me0900_device.o
-me0900-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
deleted file mode 100644
index d6ce398..0000000
--- a/drivers/staging/meilhaus/TODO
+++ /dev/null
@@ -1,10 +0,0 @@
-TODO:
- - checkpatch.pl cleanups
- - sparse issues
- - Lindent
- - audit userspace interface
- - handle firmware properly
- - possible comedi merge
-
-Please send cleanup patches to Greg Kroah-Hartman <greg at kroah.com>
-and CC: David Kiliani <mail at davidkiliani.de> and Meilhaus Support <support at meilhaus.de>
diff --git a/drivers/staging/meilhaus/me0600_device.c b/drivers/staging/meilhaus/me0600_device.c
deleted file mode 100644
index bae17d2..0000000
--- a/drivers/staging/meilhaus/me0600_device.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/**
- * @file me0600_device.c
- *
- * @brief ME-630 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#ifndef MODULE
-# define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "me0600_device.h"
-#include "mesubdevice.h"
-#include "me0600_relay.h"
-#include "me0600_ttli.h"
-#include "me0600_optoi.h"
-#include "me0600_dio.h"
-#include "me0600_ext_irq.h"
-
-me_device_t *me0600_pci_constructor(struct pci_dev *pci_device)
-{
- me0600_device_t *me0600_device;
- me_subdevice_t *subdevice;
- unsigned int version_idx;
- int err;
- int i;
-
- PDEBUG("executed.\n");
-
- // Allocate structure for device instance.
- me0600_device = kmalloc(sizeof(me0600_device_t), GFP_KERNEL);
-
- if (!me0600_device) {
- PERROR("Cannot get memory for device instance.\n");
- return NULL;
- }
-
- memset(me0600_device, 0, sizeof(me0600_device_t));
-
- // Initialize base class structure.
- err = me_device_pci_init((me_device_t *) me0600_device, pci_device);
-
- if (err) {
- kfree(me0600_device);
- PERROR("Cannot initialize device base class.\n");
- return NULL;
- }
-
- /* Get the index in the device version information table. */
- version_idx =
- me0600_versions_get_device_index(me0600_device->base.info.pci.
- device_id);
-
- // Initialize spin lock .
- spin_lock_init(&me0600_device->dio_ctrl_reg_lock);
- spin_lock_init(&me0600_device->intcsr_lock);
-
- // Create subdevice instances.
-
- for (i = 0; i < me0600_versions[version_idx].optoi_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me0600_optoi_constructor(me0600_device->
- base.info.pci.
- reg_bases[2]);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me0600_device);
- kfree(me0600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me0600_device->base.slist,
- subdevice);
- }
-
- for (i = 0; i < me0600_versions[version_idx].relay_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me0600_relay_constructor(me0600_device->
- base.info.pci.
- reg_bases[2]);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me0600_device);
- kfree(me0600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me0600_device->base.slist,
- subdevice);
- }
-
- for (i = 0; i < me0600_versions[version_idx].ttli_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me0600_ttli_constructor(me0600_device->
- base.info.pci.
- reg_bases[2]);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me0600_device);
- kfree(me0600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me0600_device->base.slist,
- subdevice);
- }
-
- for (i = 0; i < me0600_versions[version_idx].dio_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me0600_dio_constructor(me0600_device->
- base.info.pci.
- reg_bases[2], i,
- &me0600_device->
- dio_ctrl_reg_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me0600_device);
- kfree(me0600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me0600_device->base.slist,
- subdevice);
- }
-
- for (i = 0; i < me0600_versions[version_idx].ext_irq_subdevices; i++) {
- subdevice =
- (me_subdevice_t *)
- me0600_ext_irq_constructor(me0600_device->base.info.pci.
- reg_bases[1],
- me0600_device->base.info.pci.
- reg_bases[2],
- &me0600_device->intcsr_lock, i,
- me0600_device->base.irq);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me0600_device);
- kfree(me0600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me0600_device->base.slist,
- subdevice);
- }
-
- return (me_device_t *) me0600_device;
-}
-EXPORT_SYMBOL(me0600_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me0600_init(void)
-{
- PDEBUG("executed.\n");
- return 0;
-}
-
-static void __exit me0600_exit(void)
-{
- PDEBUG("executed.\n");
-}
-
-module_init(me0600_init);
-
-module_exit(me0600_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
- ("Guenter Gebhardt <g.gebhardt at meilhaus.de> & Krzysztof Gantzke <k.gantzke at meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for ME-6xx Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-6xx Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me0600_device.h b/drivers/staging/meilhaus/me0600_device.h
deleted file mode 100644
index 75bd3b7..0000000
--- a/drivers/staging/meilhaus/me0600_device.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file me0600_device.h
- *
- * @brief ME-630 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0600_DEVICE_H
-#define _ME0600_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-630 device capabilities.
- */
-typedef struct me0600_version {
- uint16_t device_id;
- unsigned int relay_subdevices;
- unsigned int ttli_subdevices;
- unsigned int optoi_subdevices;
- unsigned int dio_subdevices;
- unsigned int ext_irq_subdevices;
-} me0600_version_t;
-
-/**
- * @brief Device capabilities.
- */
-static me0600_version_t me0600_versions[] = {
- {PCI_DEVICE_ID_MEILHAUS_ME0630, 1, 1, 1, 2, 2},
- {0},
-};
-
-#define ME0600_DEVICE_VERSIONS (ARRAY_SIZE(me0600_versions) - 1) /**< Returns the number of entries in #me0600_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me0600_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me0600_versions.
- */
-static inline unsigned int me0600_versions_get_device_index(uint16_t device_id)
-{
- unsigned int i;
- for (i = 0; i < ME0600_DEVICE_VERSIONS; i++)
- if (me0600_versions[i].device_id == device_id)
- break;
- return i;
-}
-
-/**
- * @brief The ME-630 device class structure.
- */
-typedef struct me0600_device {
- me_device_t base; /**< The Meilhaus device base class. */
-
- /* Child class attributes. */
- spinlock_t dio_ctrl_reg_lock;
- spinlock_t intcsr_lock;
-} me0600_device_t;
-
-/**
- * @brief The ME-630 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-630 device instance. \n
- * NULL on error.
- */
-me_device_t *me0600_pci_constructor(struct pci_dev *pci_device)
- __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_dio.c b/drivers/staging/meilhaus/me0600_dio.c
deleted file mode 100644
index d293035..0000000
--- a/drivers/staging/meilhaus/me0600_dio.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/**
- * @file me0600_dio.c
- *
- * @brief ME-630 digital input/output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me0600_dio_reg.h"
-#include "me0600_dio.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me0600_dio_subdevice_t *instance;
- uint8_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_dio_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inb(instance->ctrl_reg);
- mode &= ~(0x3 << (instance->dio_idx * 2));
- outb(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- spin_unlock(instance->ctrl_reg_lock);
-
- outb(0x00, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->port_reg - instance->reg_base, 0x00);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_dio_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me0600_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t mode;
- int size =
- flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
- | ME_IO_SINGLE_CONFIG_DIO_WORD |
- ME_IO_SINGLE_CONFIG_DIO_DWORD);
-
- PDEBUG("executed.\n");
-
- instance = (me0600_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inb(instance->ctrl_reg);
- switch (size) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_BYTE:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
- mode &=
- ~((ME0600_DIO_CONFIG_BIT_OUT_0) <<
- (instance->dio_idx * 2));
- } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
- mode &=
- ~((ME0600_DIO_CONFIG_BIT_OUT_0) <<
- (instance->dio_idx * 2));
- mode |=
- ME0600_DIO_CONFIG_BIT_OUT_0 << (instance->
- dio_idx *
- 2);
- } else {
- PERROR
- ("Invalid port configuration specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- if (!err) {
- outb(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_dio_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me0600_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
- (instance->dio_idx * 2));
-
- if ((mode ==
- (ME0600_DIO_CONFIG_BIT_OUT_0 <<
- (instance->dio_idx * 2))) || !mode) {
- *value =
- inb(instance->
- port_reg) & (0x0001 << channel);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
- (instance->dio_idx * 2));
-
- if ((mode ==
- (ME0600_DIO_CONFIG_BIT_OUT_0 <<
- (instance->dio_idx * 2))) || !mode) {
- *value = inb(instance->port_reg) & 0x00FF;
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
-
- err = ME_ERRNO_INVALID_FLAGS;
-
- break;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_dio_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me0600_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t mode;
- uint8_t byte;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- switch (flags) {
-
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
- (instance->dio_idx * 2));
-
- if (mode ==
- (ME0600_DIO_CONFIG_BIT_OUT_0 <<
- (instance->dio_idx * 2))) {
- byte = inb(instance->port_reg);
-
- if (value)
- byte |= 0x1 << channel;
- else
- byte &= ~(0x1 << channel);
-
- outb(byte, instance->port_reg);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
- (instance->dio_idx * 2));
-
- if (mode ==
- (ME0600_DIO_CONFIG_BIT_OUT_0 <<
- (instance->dio_idx * 2))) {
- outb(value, instance->port_reg);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
-
- err = ME_ERRNO_INVALID_FLAGS;
-
- break;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_dio_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_dio_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DIO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_dio_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_DIO_DIR_BYTE;
- return ME_ERRNO_SUCCESS;
-}
-
-me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
- unsigned int dio_idx,
- spinlock_t *ctrl_reg_lock)
-{
- me0600_dio_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me0600_dio_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me0600_dio_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- /* Initialize spin locks. */
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Save digital i/o index */
- subdevice->dio_idx = dio_idx;
-
- /* Save the subdevice index */
- subdevice->ctrl_reg = reg_base + ME0600_DIO_CONFIG_REG;
- subdevice->port_reg = reg_base + ME0600_DIO_PORT_REG + dio_idx;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me0600_dio_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me0600_dio_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me0600_dio_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me0600_dio_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me0600_dio_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me0600_dio_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me0600_dio_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0600_dio.h b/drivers/staging/meilhaus/me0600_dio.h
deleted file mode 100644
index 5d075c7..0000000
--- a/drivers/staging/meilhaus/me0600_dio.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file me0600_dio.h
- *
- * @brief ME-630 digital input/output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0600_DIO_H_
-#define _ME0600_DIO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0600_dio_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
- unsigned int dio_idx; /**< The index of the digital i/o on the device. */
-
- unsigned long port_reg; /**< Register holding the port status. */
- unsigned long ctrl_reg; /**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me0600_dio_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-630 digital input/ouput subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param dio_idx The index of the digital i/o port on the device.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
- unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_dio_reg.h b/drivers/staging/meilhaus/me0600_dio_reg.h
deleted file mode 100644
index f116ea3..0000000
--- a/drivers/staging/meilhaus/me0600_dio_reg.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file me0600_dio_reg.h
- *
- * @brief ME-630 digital input/output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0600_DIO_REG_H_
-#define _ME0600_DIO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0600_DIO_CONFIG_REG 0x0007
-#define ME0600_DIO_PORT_0_REG 0x0008
-#define ME0600_DIO_PORT_1_REG 0x0009
-#define ME0600_DIO_PORT_REG ME0600_DIO_PORT_0_REG
-
-#define ME0600_DIO_CONFIG_BIT_OUT_0 0x0001
-#define ME0600_DIO_CONFIG_BIT_OUT_1 0x0004
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_ext_irq.c b/drivers/staging/meilhaus/me0600_ext_irq.c
deleted file mode 100644
index 1d09842..0000000
--- a/drivers/staging/meilhaus/me0600_ext_irq.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/**
- * @file me0600_ext_irq.c
- *
- * @brief ME-630 external interrupt subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "meids.h"
-#include "medebug.h"
-
-#include "meplx_reg.h"
-#include "me0600_ext_irq_reg.h"
-#include "me0600_ext_irq.h"
-
-/*
- * Functions
- */
-
-static int me0600_ext_irq_io_irq_start(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int irq_source,
- int irq_edge, int irq_arg, int flags)
-{
- me0600_ext_irq_subdevice_t *instance;
- uint32_t tmp;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_ext_irq_subdevice_t *) subdevice;
-
- if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (instance->lintno > 1) {
- PERROR("Wrong idx=%d.\n", instance->lintno);
- return ME_ERRNO_INVALID_SUBDEVICE;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
- PERROR("Invalid irq source specified.\n");
- return ME_ERRNO_INVALID_IRQ_SOURCE;
- }
-
- if (irq_edge != ME_IRQ_EDGE_RISING) {
- PERROR("Invalid irq edge specified.\n");
- return ME_ERRNO_INVALID_IRQ_EDGE;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- spin_lock(instance->intcsr_lock);
- tmp = inl(instance->intcsr);
- switch (instance->lintno) {
- case 0:
- tmp |=
- PLX_INTCSR_LOCAL_INT1_EN | PLX_INTCSR_LOCAL_INT1_POL |
- PLX_INTCSR_PCI_INT_EN;
- break;
- case 1:
- tmp |=
- PLX_INTCSR_LOCAL_INT2_EN | PLX_INTCSR_LOCAL_INT2_POL |
- PLX_INTCSR_PCI_INT_EN;
- break;
- }
- outl(tmp, instance->intcsr);
- PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp);
- spin_unlock(instance->intcsr_lock);
- instance->rised = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ext_irq_io_irq_wait(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int *irq_count,
- int *value, int time_out, int flags)
-{
- me0600_ext_irq_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- long t = 0;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_ext_irq_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (time_out < 0) {
- PERROR("Invalid time_out specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- t = (time_out * HZ) / 1000;
-
- if (t == 0)
- t = 1;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (instance->rised <= 0) {
- instance->rised = 0;
-
- if (time_out) {
- t = wait_event_interruptible_timeout(instance->
- wait_queue,
- (instance->rised !=
- 0), t);
-
- if (t == 0) {
- PERROR("Wait on interrupt timed out.\n");
- err = ME_ERRNO_TIMEOUT;
- }
- } else {
- wait_event_interruptible(instance->wait_queue,
- (instance->rised != 0));
- }
-
- if (instance->rised < 0) {
- PERROR("Wait on interrupt aborted by user.\n");
- err = ME_ERRNO_CANCELLED;
- }
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on interrupt aborted by signal.\n");
- err = ME_ERRNO_SIGNAL;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- instance->rised = 0;
- *irq_count = instance->n;
- *value = 1;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_ext_irq_io_irq_stop(struct me_subdevice *subdevice,
- struct file *filep,
- int channel, int flags)
-{
- me0600_ext_irq_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t tmp;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_ext_irq_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (instance->lintno > 1) {
- PERROR("Wrong idx=%d.\n", instance->lintno);
- return ME_ERRNO_INVALID_SUBDEVICE;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- spin_lock(instance->intcsr_lock);
- tmp = inl(instance->intcsr);
- switch (instance->lintno) {
- case 0:
- tmp &= ~PLX_INTCSR_LOCAL_INT1_EN;
- break;
- case 1:
- tmp &= ~PLX_INTCSR_LOCAL_INT2_EN;
- break;
- }
- outl(tmp, instance->intcsr);
- PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp);
- spin_unlock(instance->intcsr_lock);
- instance->rised = -1;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_ext_irq_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me0600_ext_irq_subdevice_t *instance;
- uint32_t tmp;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_ext_irq_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- spin_lock(instance->intcsr_lock);
- tmp = inl(instance->intcsr);
- switch (instance->lintno) {
- case 0:
- tmp |= PLX_INTCSR_LOCAL_INT1_POL | PLX_INTCSR_PCI_INT_EN;
- tmp &= ~PLX_INTCSR_LOCAL_INT1_EN;
- break;
- case 1:
- tmp |= PLX_INTCSR_LOCAL_INT2_POL | PLX_INTCSR_PCI_INT_EN;
- tmp &= ~PLX_INTCSR_LOCAL_INT2_EN;
- break;
- }
- outl(tmp, instance->intcsr);
- PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp);
- spin_unlock(instance->intcsr_lock);
-
- instance->rised = -1;
- instance->n = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ext_irq_query_number_channels(struct me_subdevice *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 1;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ext_irq_query_subdevice_type(struct me_subdevice *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_EXT_IRQ;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ext_irq_query_subdevice_caps(struct me_subdevice *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_EXT_IRQ_EDGE_RISING;
- return ME_ERRNO_SUCCESS;
-}
-
-static void me0600_ext_irq_destructor(struct me_subdevice *subdevice)
-{
- me0600_ext_irq_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_ext_irq_subdevice_t *) subdevice;
-
- free_irq(instance->irq, (void *)instance);
- me_subdevice_deinit(&instance->base);
- kfree(instance);
-}
-
-static irqreturn_t me0600_isr(int irq, void *dev_id)
-{
- me0600_ext_irq_subdevice_t *instance;
- uint32_t status;
- uint32_t mask = PLX_INTCSR_PCI_INT_EN;
- irqreturn_t ret = IRQ_HANDLED;
-
- instance = (me0600_ext_irq_subdevice_t *) dev_id;
-
- if (irq != instance->irq) {
- PERROR("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- PDEBUG("executed.\n");
-
- if (instance->lintno > 1) {
- PERROR_CRITICAL
- ("%s():Wrong subdevice index=%d plx:irq_status_reg=0x%04X.\n",
- __func__, instance->lintno, inl(instance->intcsr));
- return IRQ_NONE;
- }
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->intcsr_lock);
- status = inl(instance->intcsr);
- switch (instance->lintno) {
- case 0:
- mask |= PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_LOCAL_INT1_EN;
- break;
- case 1:
- mask |= PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_LOCAL_INT2_EN;
- break;
- }
-
- if ((status & mask) == mask) {
- instance->rised = 1;
- instance->n++;
- inb(instance->reset_reg);
- PDEBUG("Interrupt detected.\n");
- } else {
- PINFO
- ("%ld Shared interrupt. %s(): idx=0 plx:irq_status_reg=0x%04X\n",
- jiffies, __func__, status);
- ret = IRQ_NONE;
- }
- spin_unlock(instance->intcsr_lock);
- spin_unlock(&instance->subdevice_lock);
-
- wake_up_interruptible_all(&instance->wait_queue);
-
- return ret;
-}
-
-me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base,
- uint32_t me0600_reg_base,
- spinlock_t *intcsr_lock,
- unsigned ext_irq_idx,
- int irq)
-{
- me0600_ext_irq_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me0600_ext_irq_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for 630_ext_irq instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me0600_ext_irq_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->intcsr_lock = intcsr_lock;
-
- /* Initialize wait queue */
- init_waitqueue_head(&subdevice->wait_queue);
-
- subdevice->lintno = ext_irq_idx;
-
- /* Request interrupt line */
- subdevice->irq = irq;
-
- err = request_irq(subdevice->irq, me0600_isr,
- IRQF_DISABLED | IRQF_SHARED,
- ME0600_NAME, (void *)subdevice);
-
- if (err) {
- PERROR("Cannot get interrupt line.\n");
- kfree(subdevice);
- return NULL;
- }
- PINFO("Registered irq=%d.\n", subdevice->irq);
-
- /* Initialize registers */
- subdevice->intcsr = plx_reg_base + PLX_INTCSR;
- subdevice->reset_reg =
- me0600_reg_base + ME0600_INT_0_RESET_REG + ext_irq_idx;
-
- /* Initialize the subdevice methods */
- subdevice->base.me_subdevice_io_irq_start = me0600_ext_irq_io_irq_start;
- subdevice->base.me_subdevice_io_irq_wait = me0600_ext_irq_io_irq_wait;
- subdevice->base.me_subdevice_io_irq_stop = me0600_ext_irq_io_irq_stop;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me0600_ext_irq_io_reset_subdevice;
- subdevice->base.me_subdevice_query_number_channels =
- me0600_ext_irq_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me0600_ext_irq_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me0600_ext_irq_query_subdevice_caps;
- subdevice->base.me_subdevice_destructor = me0600_ext_irq_destructor;
-
- subdevice->rised = 0;
- subdevice->n = 0;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0600_ext_irq.h b/drivers/staging/meilhaus/me0600_ext_irq.h
deleted file mode 100644
index f5f2204..0000000
--- a/drivers/staging/meilhaus/me0600_ext_irq.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file me0600_ext_irq.h
- *
- * @brief ME-630 external interrupt implementation.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME0600_EXT_IRQ_H_
-#define _ME0600_EXT_IRQ_H_
-
-#include <linux/sched.h>
-
-#include "mesubdevice.h"
-#include "meslock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The ME-630 external interrupt subdevice class.
- */
-typedef struct me0600_ext_irq_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *intcsr_lock; /**< Spin lock to protect #intcsr. */
-
- wait_queue_head_t wait_queue; /**< Queue to put on threads waiting for an interrupt. */
-
- int irq; /**< The irq number assigned by PCI BIOS. */
- int rised; /**< If true an interrupt has occured. */
- unsigned int n; /**< The number of interrupt since the driver was loaded. */
- unsigned int lintno; /**< The number of the local PCI interrupt. */
-
- uint32_t intcsr; /**< The PLX interrupt control and status register. */
- uint32_t reset_reg; /**< The control register. */
-} me0600_ext_irq_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-630 external interrupt instance.
- *
- * @param plx_reg_base The register base address of the PLX chip as returned by the PCI BIOS.
- * @param me0600_reg_base The register base address of the ME-630 device as returned by the PCI BIOS.
- * @param irq The irq assigned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base,
- uint32_t me0600_reg_base,
- spinlock_t * intcsr_lock,
- unsigned int ext_irq_idx,
- int irq);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_ext_irq_reg.h b/drivers/staging/meilhaus/me0600_ext_irq_reg.h
deleted file mode 100644
index f6198fa..0000000
--- a/drivers/staging/meilhaus/me0600_ext_irq_reg.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * @file me0600_ext_irq_reg.h
- *
- * @brief ME-630 external interrupt register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME0600_EXT_IRQ_REG_H_
-#define _ME0600_EXT_IRQ_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0600_INT_0_RESET_REG 0x0005
-#define ME0600_INT_1_RESET_REG 0x0006
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_optoi.c b/drivers/staging/meilhaus/me0600_optoi.c
deleted file mode 100644
index 43f710f..0000000
--- a/drivers/staging/meilhaus/me0600_optoi.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/**
- * @file me0600_optoi.c
- *
- * @brief ME-630 Optoisolated input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me0600_optoi_reg.h"
-#include "me0600_optoi.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0600_optoi_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- PDEBUG("executed.\n");
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_optoi_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type,
- int trig_edge, int flags)
-{
- me0600_optoi_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_optoi_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
-
- switch (flags) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_BYTE:
- if (channel == 0) {
- if (single_config != ME_SINGLE_CONFIG_DIO_INPUT) {
- PERROR("Invalid port direction specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
-
- err = ME_ERRNO_INVALID_FLAGS;
-
- break;
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_optoi_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me0600_optoi_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_optoi_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
-
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- *value = inb(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = inb(instance->port_reg);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
-
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_optoi_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_optoi_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DI;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_optoi_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps = 0;
- return ME_ERRNO_SUCCESS;
-}
-
-me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base)
-{
- me0600_optoi_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me0600_optoi_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me0600_optoi_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- /* Initialize spin locks. */
- spin_lock_init(&subdevice->subdevice_lock);
-
- /* Save the subdevice index */
- subdevice->port_reg = reg_base + ME0600_OPTO_INPUT_REG;
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me0600_optoi_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me0600_optoi_io_single_config;
- subdevice->base.me_subdevice_io_single_read =
- me0600_optoi_io_single_read;
- subdevice->base.me_subdevice_query_number_channels =
- me0600_optoi_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me0600_optoi_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me0600_optoi_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0600_optoi.h b/drivers/staging/meilhaus/me0600_optoi.h
deleted file mode 100644
index e7e69bc..0000000
--- a/drivers/staging/meilhaus/me0600_optoi.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file me0600_optoi.h
- *
- * @brief ME-630 Optoisolated input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0600_OPTOI_H_
-#define _ME0600_OPTOI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0600_optoi_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
-
- uint32_t port_reg; /**< Register holding the port status. */
-} me0600_optoi_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-630 Optoisolated input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_optoi_reg.h b/drivers/staging/meilhaus/me0600_optoi_reg.h
deleted file mode 100644
index e0bc450..0000000
--- a/drivers/staging/meilhaus/me0600_optoi_reg.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file me0600_optoi_reg.h
- *
- * @brief ME-630 Optoisolated input subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0600_OPTOI_REG_H_
-#define _ME0600_OPTOI_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0600_OPTO_INPUT_REG 0x0004
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_relay.c b/drivers/staging/meilhaus/me0600_relay.c
deleted file mode 100644
index 03835e3..0000000
--- a/drivers/staging/meilhaus/me0600_relay.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/**
- * @file me0600_relay.c
- *
- * @brief ME-630 relay subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me0600_relay_reg.h"
-#include "me0600_relay.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0600_relay_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me0600_relay_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_relay_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- outb(0x0, instance->port_0_reg);
- PDEBUG_REG("port_0_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->port_0_reg - instance->reg_base, 0);
- outb(0x0, instance->port_1_reg);
- PDEBUG_REG("port_1_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->port_1_reg - instance->reg_base, 0);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_relay_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type,
- int trig_edge, int flags)
-{
- me0600_relay_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_relay_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
-
- switch (flags) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_WORD:
- if (channel == 0) {
- if (single_config != ME_SINGLE_CONFIG_DIO_OUTPUT) {
- PERROR("Invalid word direction specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
-
- err = ME_ERRNO_INVALID_FLAGS;
-
- break;
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_relay_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me0600_relay_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_relay_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
-
- switch (flags) {
-
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- *value = inb(instance->port_0_reg) & (0x1 << channel);
- } else if ((channel >= 8) && (channel < 16)) {
- *value =
- inb(instance->port_1_reg) & (0x1 << (channel - 8));
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = inb(instance->port_0_reg);
- } else if (channel == 1) {
- *value = inb(instance->port_1_reg);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_WORD:
- if (channel == 0) {
- *value = (uint32_t) inb(instance->port_1_reg) << 8;
- *value |= inb(instance->port_0_reg);
- } else {
- PERROR("Invalid word number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
-
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_relay_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me0600_relay_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t state;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_relay_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
-
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- state = inb(instance->port_0_reg);
- state =
- value ? (state | (0x1 << channel)) : (state &
- ~(0x1 <<
- channel));
- outb(state, instance->port_0_reg);
- } else if ((channel >= 8) && (channel < 16)) {
- state = inb(instance->port_1_reg);
- state =
- value ? (state | (0x1 << (channel - 8))) : (state &
- ~(0x1 <<
- (channel
- -
- 8)));
- outb(state, instance->port_1_reg);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- outb(value, instance->port_0_reg);
- } else if (channel == 1) {
- outb(value, instance->port_1_reg);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_WORD:
- if (channel == 0) {
- outb(value, instance->port_0_reg);
- outb(value >> 8, instance->port_1_reg);
- } else {
- PERROR("Invalid word number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- break;
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_relay_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 16;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_relay_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_relay_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps = 0;
- return ME_ERRNO_SUCCESS;
-}
-
-me0600_relay_subdevice_t *me0600_relay_constructor(uint32_t reg_base)
-{
- me0600_relay_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me0600_relay_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me0600_relay_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- /* Save the subdevice index */
- subdevice->port_0_reg = reg_base + ME0600_RELAIS_0_REG;
- subdevice->port_1_reg = reg_base + ME0600_RELAIS_1_REG;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me0600_relay_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me0600_relay_io_single_config;
- subdevice->base.me_subdevice_io_single_read =
- me0600_relay_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me0600_relay_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me0600_relay_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me0600_relay_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me0600_relay_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0600_relay.h b/drivers/staging/meilhaus/me0600_relay.h
deleted file mode 100644
index 2ce7dca..0000000
--- a/drivers/staging/meilhaus/me0600_relay.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file me0600_relay.h
- *
- * @brief ME-630 relay subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0600_RELAY_H_
-#define _ME0600_RELAY_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0600_relay_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
-
- unsigned long port_0_reg; /**< Register holding the port status. */
- unsigned long port_1_reg; /**< Register holding the port status. */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me0600_relay_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-630 relay subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0600_relay_subdevice_t *me0600_relay_constructor(uint32_t reg_base);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_relay_reg.h b/drivers/staging/meilhaus/me0600_relay_reg.h
deleted file mode 100644
index ba4db2e..0000000
--- a/drivers/staging/meilhaus/me0600_relay_reg.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @file me0600_relay_reg.h
- *
- * @brief ME-630 relay subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0600_RELAY_REG_H_
-#define _ME0600_RELAY_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0600_RELAIS_0_REG 0x0001
-#define ME0600_RELAIS_1_REG 0x0002
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_ttli.c b/drivers/staging/meilhaus/me0600_ttli.c
deleted file mode 100644
index 7d970f5..0000000
--- a/drivers/staging/meilhaus/me0600_ttli.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- * @file me0600_ttli.c
- *
- * @brief ME-630 TTL input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me0600_ttli_reg.h"
-#include "me0600_ttli.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0600_ttli_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- PDEBUG("executed.\n");
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ttli_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me0600_ttli_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_ttli_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
-
- switch (flags) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_BYTE:
- if (channel == 0) {
- if (single_config != ME_SINGLE_CONFIG_DIO_INPUT) {
- PERROR("Invalid port direction specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
-
- err = ME_ERRNO_INVALID_FLAGS;
-
- break;
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_ttli_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me0600_ttli_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me0600_ttli_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
-
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- *value = inb(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = inb(instance->port_reg);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0600_ttli_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ttli_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DI;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ttli_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps = 0;
- return ME_ERRNO_SUCCESS;
-}
-
-me0600_ttli_subdevice_t *me0600_ttli_constructor(uint32_t reg_base)
-{
- me0600_ttli_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me0600_ttli_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me0600_ttli_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- /* Save the subdevice index */
- subdevice->port_reg = reg_base + ME0600_TTL_INPUT_REG;
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me0600_ttli_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me0600_ttli_io_single_config;
- subdevice->base.me_subdevice_io_single_read =
- me0600_ttli_io_single_read;
- subdevice->base.me_subdevice_query_number_channels =
- me0600_ttli_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me0600_ttli_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me0600_ttli_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0600_ttli.h b/drivers/staging/meilhaus/me0600_ttli.h
deleted file mode 100644
index 6c90396..0000000
--- a/drivers/staging/meilhaus/me0600_ttli.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file me0600_ttli.h
- *
- * @brief ME-630 TTL input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0600_TTLI_H_
-#define _ME0600_TTLI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0600_ttli_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
-
- uint32_t port_reg; /**< Register holding the port status. */
-} me0600_ttli_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-630 TTL input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0600_ttli_subdevice_t *me0600_ttli_constructor(uint32_t reg_base);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_ttli_reg.h b/drivers/staging/meilhaus/me0600_ttli_reg.h
deleted file mode 100644
index 4f986d1..0000000
--- a/drivers/staging/meilhaus/me0600_ttli_reg.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file me0600_ttli_reg.h
- *
- * @brief ME-630 TTL input subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0600_TTLI_REG_H_
-#define _ME0600_TTLI_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0600_TTL_INPUT_REG 0x0003
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0900_device.c b/drivers/staging/meilhaus/me0900_device.c
deleted file mode 100644
index e9c6884..0000000
--- a/drivers/staging/meilhaus/me0900_device.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/**
- * @file me0900_device.c
- *
- * @brief ME-9x device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
-*/
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#ifndef MODULE
-# define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "me0900_device.h"
-#include "me0900_reg.h"
-#include "mesubdevice.h"
-#include "me0900_do.h"
-#include "me0900_di.h"
-
-me_device_t *me0900_pci_constructor(struct pci_dev *pci_device)
-{
- me0900_device_t *me0900_device;
- me_subdevice_t *subdevice;
- unsigned int version_idx;
- int err;
- int i;
- int port_shift;
-
- PDEBUG("executed.\n");
-
- // Allocate structure for device instance.
- me0900_device = kmalloc(sizeof(me0900_device_t), GFP_KERNEL);
-
- if (!me0900_device) {
- PERROR("Cannot get memory for device instance.\n");
- return NULL;
- }
-
- memset(me0900_device, 0, sizeof(me0900_device_t));
-
- // Initialize base class structure.
- err = me_device_pci_init((me_device_t *) me0900_device, pci_device);
-
- if (err) {
- kfree(me0900_device);
- PERROR("Cannot initialize device base class.\n");
- return NULL;
- }
-
- /* Get the index in the device version information table. */
- version_idx =
- me0900_versions_get_device_index(me0900_device->base.info.pci.
- device_id);
-
- /* Initialize 8255 chip to desired mode */
- if (me0900_device->base.info.pci.device_id ==
- PCI_DEVICE_ID_MEILHAUS_ME0940) {
- outb(0x9B,
- me0900_device->base.info.pci.reg_bases[2] +
- ME0900_CTRL_REG);
- } else if (me0900_device->base.info.pci.device_id ==
- PCI_DEVICE_ID_MEILHAUS_ME0950) {
- outb(0x89,
- me0900_device->base.info.pci.reg_bases[2] +
- ME0900_CTRL_REG);
- outb(0x00,
- me0900_device->base.info.pci.reg_bases[2] +
- ME0900_WRITE_ENABLE_REG);
- } else if (me0900_device->base.info.pci.device_id ==
- PCI_DEVICE_ID_MEILHAUS_ME0960) {
- outb(0x8B,
- me0900_device->base.info.pci.reg_bases[2] +
- ME0900_CTRL_REG);
- outb(0x00,
- me0900_device->base.info.pci.reg_bases[2] +
- ME0900_WRITE_ENABLE_REG);
- }
-
- port_shift =
- (me0900_device->base.info.pci.device_id ==
- PCI_DEVICE_ID_MEILHAUS_ME0960) ? 1 : 0;
- // Create subdevice instances.
-
- for (i = 0; i < me0900_versions[version_idx].di_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me0900_di_constructor(me0900_device->
- base.info.pci.
- reg_bases[2],
- i + port_shift);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me0900_device);
- kfree(me0900_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me0900_device->base.slist,
- subdevice);
- }
-
- for (i = 0; i < me0900_versions[version_idx].do_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me0900_do_constructor(me0900_device->
- base.info.pci.
- reg_bases[2], i);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me0900_device);
- kfree(me0900_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me0900_device->base.slist,
- subdevice);
- }
-
- return (me_device_t *) me0900_device;
-}
-EXPORT_SYMBOL(me0900_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me0900_init(void)
-{
- PDEBUG("executed.\n.");
- return 0;
-}
-
-static void __exit me0900_exit(void)
-{
- PDEBUG("executed.\n.");
-}
-
-module_init(me0900_init);
-module_exit(me0900_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
- ("Guenter Gebhardt <g.gebhardt at meilhaus.de> & Krzysztof Gantzke <k.gantzke at meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for ME-9x Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-9x Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me0900_device.h b/drivers/staging/meilhaus/me0900_device.h
deleted file mode 100644
index 53c05e8..0000000
--- a/drivers/staging/meilhaus/me0900_device.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * @file me0900_device.h
- *
- * @brief ME-0900 (ME-9x) device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0900_DEVICE_H
-#define _ME0900_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-0900 (ME-9x) device capabilities.
- */
-typedef struct me0900_version {
- uint16_t device_id;
- unsigned int di_subdevices;
- unsigned int do_subdevices;
-} me0900_version_t;
-
-/**
- * @brief Device capabilities.
- */
-static me0900_version_t me0900_versions[] = {
- {PCI_DEVICE_ID_MEILHAUS_ME0940, 2, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME0950, 0, 2},
- {PCI_DEVICE_ID_MEILHAUS_ME0960, 1, 1},
- {0},
-};
-
-#define ME0900_DEVICE_VERSIONS (ARRAY_SIZE(me0900_versions) - 1) /**< Returns the number of entries in #me0900_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me0900_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me0900_versions.
- */
-static inline unsigned int me0900_versions_get_device_index(uint16_t device_id)
-{
- unsigned int i;
- for (i = 0; i < ME0900_DEVICE_VERSIONS; i++)
- if (me0900_versions[i].device_id == device_id)
- break;
- return i;
-}
-
-/**
- * @brief The ME-0900 (ME-9x) device class structure.
- */
-typedef struct me0900_device {
- me_device_t base; /**< The Meilhaus device base class. */
-} me0900_device_t;
-
-/**
- * @brief The ME-9x device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-0900 (ME-9x) device instance. \n
- * NULL on error.
- */
-me_device_t *me0900_pci_constructor(struct pci_dev *pci_device)
- __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0900_di.c b/drivers/staging/meilhaus/me0900_di.c
deleted file mode 100644
index b8c448f..0000000
--- a/drivers/staging/meilhaus/me0900_di.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- * @file me0900_di.c
- *
- * @brief ME-9x digital input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "meids.h"
-#include "medebug.h"
-#include "meplx_reg.h"
-#include "me0900_reg.h"
-#include "me0900_di.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0900_di_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- PDEBUG("executed.\n");
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_di_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me0900_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me0900_di_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- switch (flags) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
- } else {
- PERROR("Invalid byte direction specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0900_di_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me0900_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me0900_di_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- *value = (~inb(instance->port_reg)) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = ~inb(instance->port_reg);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0900_di_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_di_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DI;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- PDEBUG("executed.\n");
- *caps = 0;
- return ME_ERRNO_SUCCESS;
-}
-
-me0900_di_subdevice_t *me0900_di_constructor(uint32_t reg_base,
- unsigned int di_idx)
-{
- me0900_di_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me0900_di_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me0900_di_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- /* Save the subdevice index. */
- subdevice->di_idx = di_idx;
-
- /* Initialize registers */
- if (di_idx == 0) {
- subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
- subdevice->port_reg = reg_base + ME0900_PORT_A_REG;
- } else {
- subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
- subdevice->port_reg = reg_base + ME0900_PORT_B_REG;
- }
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me0900_di_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me0900_di_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me0900_di_io_single_read;
- subdevice->base.me_subdevice_query_number_channels =
- me0900_di_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me0900_di_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me0900_di_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0900_di.h b/drivers/staging/meilhaus/me0900_di.h
deleted file mode 100644
index 014f134..0000000
--- a/drivers/staging/meilhaus/me0900_di.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * @file me0900_di.h
- *
- * @brief ME-9x digital input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0900_DI_H_
-#define _ME0900_DI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0900_di_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
-
- unsigned int di_idx;
-
- unsigned long ctrl_reg;
- unsigned long port_reg;
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me0900_di_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-9x digital input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0900_di_subdevice_t *me0900_di_constructor(uint32_t me0900_reg_base,
- unsigned int di_idx);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0900_do.c b/drivers/staging/meilhaus/me0900_do.c
deleted file mode 100644
index a2275fa..0000000
--- a/drivers/staging/meilhaus/me0900_do.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/**
- * @file me0900_do.c
- *
- * @brief ME-9x digital output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me0900_reg.h"
-#include "me0900_do.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0900_do_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me0900_do_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me0900_do_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- outb(0xFF, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->port_reg - instance->reg_base, 0xff);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_do_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me0900_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me0900_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- switch (flags) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
- } else {
- PERROR("Invalid byte direction specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0900_do_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me0900_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me0900_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- *value = (~inb(instance->port_reg)) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = ~inb(instance->port_reg);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0900_do_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me0900_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long state;
-
- PDEBUG("executed.\n");
-
- instance = (me0900_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- state = inb(instance->port_reg);
- state =
- (!value) ? (state | (0x1 << channel)) : (state &
- ~(0x1 <<
- channel));
- outb(state, instance->port_reg);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- outb(~(value), instance->port_reg);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me0900_do_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_do_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- PDEBUG("executed.\n");
- *caps = 0;
- return ME_ERRNO_SUCCESS;
-}
-
-me0900_do_subdevice_t *me0900_do_constructor(uint32_t reg_base,
- unsigned int do_idx)
-{
- me0900_do_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me0900_do_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me0900_do_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- /* Save the subdevice index */
- subdevice->do_idx = do_idx;
-
- /* Initialize registers */
- if (do_idx == 0) {
- subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
- subdevice->port_reg = reg_base + ME0900_PORT_A_REG;
- subdevice->enable_reg = reg_base + ME0900_WRITE_ENABLE_REG;
- subdevice->disable_reg = reg_base + ME0900_WRITE_DISABLE_REG;
- } else {
- subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
- subdevice->port_reg = reg_base + ME0900_PORT_B_REG;
- subdevice->enable_reg = reg_base + ME0900_WRITE_ENABLE_REG;
- subdevice->disable_reg = reg_base + ME0900_WRITE_DISABLE_REG;
- }
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me0900_do_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me0900_do_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me0900_do_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me0900_do_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me0900_do_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me0900_do_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me0900_do_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0900_do.h b/drivers/staging/meilhaus/me0900_do.h
deleted file mode 100644
index 13e8a8b..0000000
--- a/drivers/staging/meilhaus/me0900_do.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file me0900_do.h
- *
- * @brief ME-9x digital output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0900_DO_H_
-#define _ME0900_DO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0900_do_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
-
- unsigned int do_idx;
-
- unsigned long ctrl_reg;
- unsigned long port_reg;
- unsigned long enable_reg;
- unsigned long disable_reg;
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me0900_do_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-9x digital output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param do_idx The index of the digital output subdevice on this device.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0900_do_subdevice_t *me0900_do_constructor(uint32_t reg_base,
- unsigned int do_idx);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0900_reg.h b/drivers/staging/meilhaus/me0900_reg.h
deleted file mode 100644
index 3bf163b..0000000
--- a/drivers/staging/meilhaus/me0900_reg.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @file me0900_reg.h
- *
- * @brief ME-9x register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME0900_REG_H_
-#define _ME0900_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0900_PORT_A_REG 0x00
-#define ME0900_PORT_B_REG 0x01
-#define ME0900_PORT_C_REG 0x02
-#define ME0900_CTRL_REG 0x03 // ( ,w)
-#define ME0900_WRITE_ENABLE_REG 0x04 // (r,w)
-#define ME0900_WRITE_DISABLE_REG 0x08 // (r,w)
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1000_device.c b/drivers/staging/meilhaus/me1000_device.c
deleted file mode 100644
index cf0fb92..0000000
--- a/drivers/staging/meilhaus/me1000_device.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/**
- * @file me1000_device.c
- *
- * @brief ME-1000 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#ifndef MODULE
-# define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "me1000_device.h"
-#include "mesubdevice.h"
-#include "me1000_dio.h"
-
-static int me1000_config_load(me_device_t *me_device, struct file *filep,
- me_cfg_device_entry_t *config)
-{
- me1000_device_t *me1000_device;
- me1000_dio_subdevice_t *dio;
-
- PDEBUG("executed.\n");
-
- me1000_device = (me1000_device_t *) me_device;
-
- if (config->count == 2) {
- if (me_slist_get_number_subdevices(&me1000_device->base.slist)
- == 2) {
- // Nothing to do.
- } else {
- // Remove 2 extra subdevices
- dio =
- (me1000_dio_subdevice_t *)
- me_slist_del_subdevice_tail(&me1000_device->base.
- slist);
- if (dio)
- dio->base.
- me_subdevice_destructor((me_subdevice_t *)
- dio);
-
- dio =
- (me1000_dio_subdevice_t *)
- me_slist_del_subdevice_tail(&me1000_device->base.
- slist);
- if (dio)
- dio->base.
- me_subdevice_destructor((me_subdevice_t *)
- dio);
- }
- } else if (config->count == 4) {
- //Add 2 subdevices
- if (me_slist_get_number_subdevices(&me1000_device->base.slist)
- == 2) {
- dio =
- me1000_dio_constructor(me1000_device->base.info.pci.
- reg_bases[2], 2,
- &me1000_device->ctrl_lock);
- if (!dio) {
- PERROR("Cannot create dio subdevice.\n");
- return ME_ERRNO_INTERNAL;
- }
- me_slist_add_subdevice_tail(&me1000_device->base.slist,
- (me_subdevice_t *) dio);
-
- dio =
- me1000_dio_constructor(me1000_device->base.info.pci.
- reg_bases[2], 3,
- &me1000_device->ctrl_lock);
- if (!dio) {
- dio =
- (me1000_dio_subdevice_t *)
- me_slist_del_subdevice_tail(&me1000_device->
- base.slist);
- if (dio)
- dio->base.
- me_subdevice_destructor((me_subdevice_t *) dio);
-
- PERROR("Cannot create dio subdevice.\n");
- return ME_ERRNO_INTERNAL;
- }
- me_slist_add_subdevice_tail(&me1000_device->base.slist,
- (me_subdevice_t *) dio);
- } else {
- // Nothing to do.
- }
- } else {
- PERROR("Invalid configuration.\n");
- return ME_ERRNO_INTERNAL;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-me_device_t *me1000_pci_constructor(struct pci_dev * pci_device)
-{
- me1000_device_t *me1000_device;
- me_subdevice_t *subdevice;
- int err;
- int i;
-
- PDEBUG("executed.\n");
-
- // Allocate structure for device instance.
- me1000_device = kmalloc(sizeof(me1000_device_t), GFP_KERNEL);
-
- if (!me1000_device) {
- PERROR("Cannot get memory for ME-1000 device instance.\n");
- return NULL;
- }
-
- memset(me1000_device, 0, sizeof(me1000_device_t));
-
- // Initialize base class structure.
- err = me_device_pci_init((me_device_t *) me1000_device, pci_device);
-
- if (err) {
- kfree(me1000_device);
- PERROR("Cannot initialize device base class.\n");
- return NULL;
- }
- // Initialize spin lock .
- spin_lock_init(&me1000_device->ctrl_lock);
-
- for (i = 0; i < 4; i++) {
- subdevice =
- (me_subdevice_t *) me1000_dio_constructor(me1000_device->
- base.info.pci.
- reg_bases[2], i,
- &me1000_device->
- ctrl_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me1000_device);
- kfree(me1000_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me1000_device->base.slist,
- subdevice);
- }
-
- // Overwrite base class methods.
- me1000_device->base.me_device_config_load = me1000_config_load;
-
- return (me_device_t *) me1000_device;
-}
-EXPORT_SYMBOL(me1000_pci_constructor);
-
-// Init and exit of module.
-static int __init me1000_init(void)
-{
- PDEBUG("executed.\n");
- return 0;
-}
-
-static void __exit me1000_exit(void)
-{
- PDEBUG("executed.\n");
-}
-
-module_init(me1000_init);
-module_exit(me1000_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
- ("Guenter Gebhardt <g.gebhardt at meilhaus.de> & Krzysztof Gantzke <k.gantzke at meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-1000 Devices");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-1000 Digital I/O Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me1000_device.h b/drivers/staging/meilhaus/me1000_device.h
deleted file mode 100644
index cbbe126..0000000
--- a/drivers/staging/meilhaus/me1000_device.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file me1000_device.h
- *
- * @brief ME-1000 device class instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME1000_H_
-#define _ME1000_H_
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-#define ME1000_MAGIC_NUMBER 1000
-
-/**
- * @brief The ME-1000 device class structure.
- */
-typedef struct me1000_device {
- me_device_t base; /**< The Meilhaus device base class. */
- spinlock_t ctrl_lock; /**< Guards the DIO mode register. */
-} me1000_device_t;
-
-/**
- * @brief The ME-1000 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-1000 device instance. \n
- * NULL on error.
- */
-me_device_t *me1000_pci_constructor(struct pci_dev *pci_device)
- __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1000_dio.c b/drivers/staging/meilhaus/me1000_dio.c
deleted file mode 100644
index 2d7ed07..0000000
--- a/drivers/staging/meilhaus/me1000_dio.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/**
- * @file me1000_dio.c
- *
- * @brief ME-1000 DIO subdevice instance.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2006 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "medebug.h"
-
-#include "me1000_dio_reg.h"
-#include "me1000_dio.h"
-
-/*
- * Defines
- */
-#define ME1000_DIO_MAGIC_NUMBER 0x1000 /**< The magic number of the class structure. */
-
-/*
- * Functions
- */
-
-static int me1000_dio_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me1000_dio_subdevice_t *instance;
- uint32_t tmp;
-
- PDEBUG("executed.\n");
-
- instance = (me1000_dio_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
- tmp &= ~(0x1 << instance->dio_idx);
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- spin_unlock(instance->ctrl_reg_lock);
-
- outl(0x00000000, instance->port_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, 0);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1000_dio_io_single_config(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me1000_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- int ctrl;
- int size =
- flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
- | ME_IO_SINGLE_CONFIG_DIO_WORD |
- ME_IO_SINGLE_CONFIG_DIO_DWORD);
-
- PDEBUG("executed.\n");
-
- instance = (me1000_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- ctrl = inl(instance->ctrl_reg);
-
- switch (size) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_DWORD:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
- ctrl &= ~(0x1 << instance->dio_idx);
- } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
- ctrl |= 0x1 << instance->dio_idx;
- } else {
- PERROR("Invalid port direction.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- if (!err) {
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me1000_dio_io_single_read(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me1000_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me1000_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 32)) {
- *value = inl(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if ((channel >= 0) && (channel < 4)) {
- *value =
- (inl(instance->port_reg) >> (channel * 8)) & 0xFF;
- } else {
- PERROR("Invalid byte number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_TYPE_DIO_WORD:
- if ((channel >= 0) && (channel < 2)) {
- *value =
- (inl(instance->port_reg) >> (channel * 16)) &
- 0xFFFF;
- } else {
- PERROR("Invalid word number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_DWORD:
- if (channel == 0) {
- *value = inl(instance->port_reg);
- } else {
- PERROR("Invalid dword number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me1000_dio_io_single_write(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me1000_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t config;
- uint32_t state;
-
- PDEBUG("executed.\n");
-
- instance = (me1000_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- config = inl(instance->ctrl_reg) & (0x1 << instance->dio_idx);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 32)) {
- if (config) {
- state = inl(instance->port_reg);
- state =
- value ? (state | (0x1 << channel)) : (state
- &
- ~(0x1
- <<
- channel));
- outl(state, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg -
- instance->reg_base, state);
- } else {
- PERROR("Port is not in output mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid bit number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if ((channel >= 0) && (channel < 4)) {
- if (config) {
- state = inl(instance->port_reg);
- state &= ~(0xFF << (channel * 8));
- state |= (value & 0xFF) << (channel * 8);
- outl(state, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg -
- instance->reg_base, state);
- } else {
- PERROR("Port is not in output mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid byte number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_TYPE_DIO_WORD:
- if ((channel >= 0) && (channel < 2)) {
- if (config) {
- state = inl(instance->port_reg);
- state &= ~(0xFFFF << (channel * 16));
- state |= (value & 0xFFFF) << (channel * 16);
- outl(state, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg -
- instance->reg_base, state);
- } else {
- PERROR("Port is not in output mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid word number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_DWORD:
- if (channel == 0) {
- if (config) {
- outl(value, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg -
- instance->reg_base, value);
- } else {
- PERROR("Port is not in output mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid dword number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me1000_dio_query_number_channels(struct me_subdevice *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = ME1000_DIO_NUMBER_CHANNELS;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1000_dio_query_subdevice_type(struct me_subdevice *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DIO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1000_dio_query_subdevice_caps(struct me_subdevice *subdevice,
- int *caps)
-{
- me1000_dio_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me1000_dio_subdevice_t *) subdevice;
-
- *caps = ME_CAPS_DIO_DIR_DWORD;
-
- return ME_ERRNO_SUCCESS;
-}
-
-me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base,
- unsigned int dio_idx,
- spinlock_t *ctrl_reg_lock)
-{
- me1000_dio_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me1000_dio_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for ME-1000 DIO instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me1000_dio_subdevice_t));
-
- /* Check if counter index is out of range */
-
- if (dio_idx >= ME1000_DIO_NUMBER_PORTS) {
- PERROR("DIO index is out of range.\n");
- kfree(subdevice);
- return NULL;
- }
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Save the DIO index */
- subdevice->dio_idx = dio_idx;
-
- /* Initialize registers. */
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
- subdevice->ctrl_reg = reg_base + ME1000_PORT_MODE;
- subdevice->port_reg =
- reg_base + ME1000_PORT + (dio_idx * ME1000_PORT_STEP);
-
- /* Override base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me1000_dio_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me1000_dio_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me1000_dio_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me1000_dio_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me1000_dio_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me1000_dio_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me1000_dio_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me1000_dio.h b/drivers/staging/meilhaus/me1000_dio.h
deleted file mode 100644
index d26e93f..0000000
--- a/drivers/staging/meilhaus/me1000_dio.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * @file me1000_dio.h
- *
- * @brief Meilhaus ME-1000 digital i/o implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME1000_DIO_H_
-#define _ME1000_DIO_H_
-
-#include "mesubdevice.h"
-#include "meslock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The ME-1000 DIO subdevice class.
- */
-typedef struct me1000_dio_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
-// uint32_t magic; /**< The magic number unique for this structure. */
-
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg and #ctrl_reg_mirror from concurrent access. */
- int dio_idx; /**< The index of the DIO port on the device. */
-
- unsigned long port_reg; /**< Register to read or write a value from or to the port respectively. */
- unsigned long ctrl_reg; /**< Register to configure the DIO modes. */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me1000_dio_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-1000 DIO instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param dio_idx The index of the DIO on the device.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register and from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base,
- unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1000_dio_reg.h b/drivers/staging/meilhaus/me1000_dio_reg.h
deleted file mode 100644
index 4d5b38d..0000000
--- a/drivers/staging/meilhaus/me1000_dio_reg.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file me1000_dio_reg.h
- *
- * @brief ME-1000 digital i/o register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME1000_DIO_REG_H_
-# define _ME1000_DIO_REG_H_
-
-# ifdef __KERNEL__
-
-# define ME1000_DIO_NUMBER_CHANNELS 32 /**< The number of channels per DIO port. */
-# define ME1000_DIO_NUMBER_PORTS 4 /**< The number of ports per ME-1000. */
-
-// # define ME1000_PORT_A 0x0000 /**< Port A base register offset. */
-// # define ME1000_PORT_B 0x0004 /**< Port B base register offset. */
-// # define ME1000_PORT_C 0x0008 /**< Port C base register offset. */
-// # define ME1000_PORT_D 0x000C /**< Port D base register offset. */
-# define ME1000_PORT 0x0000 /**< Base for port's register. */
-# define ME1000_PORT_STEP 4 /**< Distance between port's register. */
-
-# define ME1000_PORT_MODE 0x0010 /**< Configuration register to switch the port direction. */
-// # define ME1000_PORT_MODE_OUTPUT_A (1 << 0) /**< If set, port A is in output, otherwise in input mode. */
-// # define ME1000_PORT_MODE_OUTPUT_B (1 << 1) /**< If set, port B is in output, otherwise in input mode. */
-// # define ME1000_PORT_MODE_OUTPUT_C (1 << 2) /**< If set, port C is in output, otherwise in input mode. */
-// # define ME1000_PORT_MODE_OUTPUT_D (1 << 3) /**< If set, port D is in output, otherwise in input mode. */
-
-# endif //__KERNEL__
-#endif //_ME1000_DIO_REG_H_
diff --git a/drivers/staging/meilhaus/me1400_device.c b/drivers/staging/meilhaus/me1400_device.c
deleted file mode 100644
index a018b5f..0000000
--- a/drivers/staging/meilhaus/me1400_device.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * @file me1400_device.c
- *
- * @brief ME-1400 device instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * User application could also include the kernel header files. But the
- * real kernel functions are protected by #ifdef __KERNEL__.
- */
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * This must be defined before module.h is included. Not needed, when
- * it is a built in driver.
- */
-#ifndef MODULE
-# define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-
-#include "me1400_device.h"
-#include "me8254.h"
-#include "me8254_reg.h"
-#include "me8255.h"
-#include "me1400_ext_irq.h"
-
-me_device_t *me1400_pci_constructor(struct pci_dev *pci_device)
-{
- int err;
- me1400_device_t *me1400_device;
- me_subdevice_t *subdevice;
- unsigned int version_idx;
- unsigned int me8255_idx;
- unsigned int dio_idx;
- unsigned int me8254_idx;
- unsigned int ctr_idx;
- unsigned int ext_irq_idx;
-
- PDEBUG("executed.\n");
-
- // Allocate structure for device instance.
- me1400_device = kmalloc(sizeof(me1400_device_t), GFP_KERNEL);
-
- if (!me1400_device) {
- PERROR("Cannot get memory for 1400ate device instance.\n");
- return NULL;
- }
-
- memset(me1400_device, 0, sizeof(me1400_device_t));
-
- // Initialize base class structure.
- err = me_device_pci_init((me_device_t *) me1400_device, pci_device);
-
- if (err) {
- kfree(me1400_device);
- PERROR("Cannot initialize device base class.\n");
- return NULL;
- }
-
- /* Check for ME1400 extension device. If detected we fake a ME-1400 D device id. */
- if (me1400_device->base.info.pci.device_id ==
- PCI_DEVICE_ID_MEILHAUS_ME140C) {
- uint8_t ctrl;
- ctrl =
- inb(me1400_device->base.info.pci.reg_bases[2] +
- ME1400D_CLK_SRC_2_REG);
- PDEBUG_REG("xxx_reg inb(0x%X+0x%X)=0x%x\n",
- me1400_device->base.info.pci.reg_bases[2],
- ME1400D_CLK_SRC_2_REG, ctrl);
- outb(ctrl | 0xF0,
- me1400_device->base.info.pci.reg_bases[2] +
- ME1400D_CLK_SRC_2_REG);
- PDEBUG_REG("xxx_reg outb(0x%X+0x%X)=0x%x\n",
- me1400_device->base.info.pci.reg_bases[2],
- ME1400D_CLK_SRC_2_REG, ctrl | 0xF0);
- ctrl =
- inb(me1400_device->base.info.pci.reg_bases[2] +
- ME1400D_CLK_SRC_2_REG);
- PDEBUG_REG("xxx_reg inb(0x%X+0x%X)=0x%x\n",
- me1400_device->base.info.pci.reg_bases[2],
- ME1400D_CLK_SRC_2_REG, ctrl);
-
- if ((ctrl & 0xF0) == 0xF0) {
- PINFO("ME1400 D detected.\n");
- me1400_device->base.info.pci.device_id =
- PCI_DEVICE_ID_MEILHAUS_ME140D;
- }
- }
-
- /* Initialize global stuff of digital i/o subdevices. */
- for (me8255_idx = 0; me8255_idx < ME1400_MAX_8255; me8255_idx++) {
- me1400_device->dio_current_mode[me8255_idx] = 0;
- spin_lock_init(&me1400_device->dio_ctrl_reg_lock[me8255_idx]);
- }
-
- /* Initialize global stuff of counter subdevices. */
- spin_lock_init(&me1400_device->clk_src_reg_lock);
-
- for (me8254_idx = 0; me8254_idx < ME1400_MAX_8254; me8254_idx++)
- spin_lock_init(&me1400_device->ctr_ctrl_reg_lock[me8254_idx]);
-
- /* Get the index in the device version information table. */
- version_idx =
- me1400_versions_get_device_index(me1400_device->base.info.pci.
- device_id);
-
- /* Generate DIO subdevice instances. */
- for (me8255_idx = 0;
- me8255_idx < me1400_versions[version_idx].dio_chips;
- me8255_idx++) {
- for (dio_idx = 0; dio_idx < 3; dio_idx++) {
- subdevice =
- (me_subdevice_t *)
- me8255_constructor(me1400_versions[version_idx].
- device_id,
- me1400_device->base.info.pci.
- reg_bases[2], me8255_idx,
- dio_idx,
- &me1400_device->
- dio_current_mode[me8255_idx],
- &me1400_device->
- dio_ctrl_reg_lock[me8255_idx]);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me1400_device);
- kfree(me1400_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me1400_device->base.slist,
- subdevice);
- }
- }
-
- /* Generate counter subdevice instances. */
- for (me8254_idx = 0;
- me8254_idx < me1400_versions[version_idx].ctr_chips;
- me8254_idx++) {
- for (ctr_idx = 0; ctr_idx < 3; ctr_idx++) {
- subdevice =
- (me_subdevice_t *)
- me8254_constructor(me1400_device->base.info.pci.
- device_id,
- me1400_device->base.info.pci.
- reg_bases[2], me8254_idx,
- ctr_idx,
- &me1400_device->
- ctr_ctrl_reg_lock[me8254_idx],
- &me1400_device->
- clk_src_reg_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me1400_device);
- kfree(me1400_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me1400_device->base.slist,
- subdevice);
- }
- }
-
- /* Generate external interrupt subdevice instances. */
- for (ext_irq_idx = 0;
- ext_irq_idx < me1400_versions[version_idx].ext_irq_subdevices;
- ext_irq_idx++) {
- subdevice =
- (me_subdevice_t *)
- me1400_ext_irq_constructor(me1400_device->base.info.pci.
- device_id,
- me1400_device->base.info.pci.
- reg_bases[1],
- me1400_device->base.info.pci.
- reg_bases[2],
- &me1400_device->clk_src_reg_lock,
- me1400_device->base.irq);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me1400_device);
- kfree(me1400_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me1400_device->base.slist,
- subdevice);
- }
-
- return (me_device_t *) me1400_device;
-}
-EXPORT_SYMBOL(me1400_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me1400_init(void)
-{
- PDEBUG("executed.\n");
- return 0;
-}
-
-static void __exit me1400_exit(void)
-{
- PDEBUG("executed.\n");
-}
-
-module_init(me1400_init);
-module_exit(me1400_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
- ("Guenter Gebhardt <g.gebhardt at meilhaus.de> & Krzysztof Gantzke <k.gantzke at meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-14xx devices");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-14xx MIO devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me1400_device.h b/drivers/staging/meilhaus/me1400_device.h
deleted file mode 100644
index d20112d..0000000
--- a/drivers/staging/meilhaus/me1400_device.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * @file me1400_device.c
- *
- * @brief ME-1400 device family instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME1400_DEVICE_H_
-#define _ME1400_DEVICE_H_
-
-#include "metypes.h"
-#include "medefines.h"
-#include "meinternal.h"
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure to store device capabilities.
- */
-typedef struct me1400_version {
- uint16_t device_id; /**< The PCI device id of the device. */
- unsigned int dio_chips; /**< The number of 8255 chips on the device. */
- unsigned int ctr_chips; /**< The number of 8254 chips on the device. */
- unsigned int ext_irq_subdevices; /**< The number of external interrupt inputs on the device. */
-} me1400_version_t;
-
-/**
- * @brief Defines for each ME-1400 device version its capabilities.
- */
-static me1400_version_t me1400_versions[] = {
- {PCI_DEVICE_ID_MEILHAUS_ME1400, 1, 0, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME140A, 1, 1, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME140B, 2, 2, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME14E0, 1, 0, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME14EA, 1, 1, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME14EB, 2, 2, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME140C, 1, 5, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME140D, 2, 10, 1},
- {0}
-};
-
-#define ME1400_DEVICE_VERSIONS (ARRAY_SIZE(me1400_versions) - 1) /**< Returns the number of entries in #me1400_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me1400_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me1400_versions.
- */
-static inline unsigned int me1400_versions_get_device_index(uint16_t device_id)
-{
- unsigned int i;
- for (i = 0; i < ME1400_DEVICE_VERSIONS; i++)
- if (me1400_versions[i].device_id == device_id)
- break;
- return i;
-}
-
-#define ME1400_MAX_8254 10 /**< The maximum number of 8254 counter subdevices available on any ME-1400 device. */
-#define ME1400_MAX_8255 2 /**< The maximum number of 8255 digital i/o subdevices available on any ME-1400 device. */
-
-/**
- * @brief The ME-1400 device class.
- */
-typedef struct me1400_device {
- me_device_t base; /**< The Meilhaus device base class. */
-
- spinlock_t clk_src_reg_lock; /**< Guards the 8254 clock source registers. */
- spinlock_t ctr_ctrl_reg_lock[ME1400_MAX_8254]; /**< Guards the 8254 ctrl registers. */
-
- int dio_current_mode[ME1400_MAX_8255]; /**< Saves the current mode setting of a single 8255 DIO chip. */
- spinlock_t dio_ctrl_reg_lock[ME1400_MAX_8255]; /**< Guards the 8255 ctrl register and #dio_current_mode. */
-} me1400_device_t;
-
-/**
- * @brief The ME-1400 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-1400 device instance. \n
- * NULL on error.
- */
-me_device_t *me1400_pci_constructor(struct pci_dev *pci_device)
- __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1400_ext_irq.c b/drivers/staging/meilhaus/me1400_ext_irq.c
deleted file mode 100644
index 6841f41..0000000
--- a/drivers/staging/meilhaus/me1400_ext_irq.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/**
- * @file me1400_ext_irq.c
- *
- * @brief ME-1400 external interrupt subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "medebug.h"
-#include "meids.h"
-
-#include "me1400_ext_irq.h"
-#include "me1400_ext_irq_reg.h"
-
-/*
- * Defines
- */
-#define ME1400_EXT_IRQ_MAGIC_NUMBER 0x1401 /**< The magic number of the class structure. */
-#define ME1400_EXT_IRQ_NUMBER_CHANNELS 1 /**< One channel per counter. */
-
-/*
- * Functions
- */
-
-static int me1400_ext_irq_io_irq_start(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int irq_source,
- int irq_edge, int irq_arg, int flags)
-{
- me1400_ext_irq_subdevice_t *instance;
- unsigned long cpu_flags;
- uint8_t tmp;
-
- PDEBUG("executed.\n");
-
- instance = (me1400_ext_irq_subdevice_t *) subdevice;
-
- if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
- PERROR("Invalid irq source.\n");
- return ME_ERRNO_INVALID_IRQ_SOURCE;
- }
-
- if (irq_edge != ME_IRQ_EDGE_RISING) {
- PERROR("Invalid irq edge.\n");
- return ME_ERRNO_INVALID_IRQ_EDGE;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
- spin_lock(instance->clk_src_reg_lock);
-// // Enable IRQ on PLX
-// tmp = inb(instance->plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN);
-// outb(tmp, instance->plx_intcs_reg);
-// PDEBUG_REG("ctrl_reg outb(PLX:0x%lX)=0x%x\n", instance->plx_intcs_reg, tmp);
-
- // Enable IRQ
- switch (instance->device_id) {
- case PCI_DEVICE_ID_MEILHAUS_ME140C:
- case PCI_DEVICE_ID_MEILHAUS_ME140D:
- tmp = inb(instance->ctrl_reg);
- tmp |= ME1400CD_EXT_IRQ_CLK_EN;
- outb(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- break;
-
- default:
- outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ME1400AB_EXT_IRQ_IRQ_EN);
- break;
- }
- spin_unlock(instance->clk_src_reg_lock);
- instance->rised = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1400_ext_irq_io_irq_wait(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int *irq_count,
- int *value, int time_out, int flags)
-{
- me1400_ext_irq_subdevice_t *instance;
- unsigned long cpu_flags;
- long t = 0;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me1400_ext_irq_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (time_out < 0) {
- PERROR("Invalid time out.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- /* Convert to ticks */
- t = (time_out * HZ) / 1000;
-
- if (t == 0)
- t = 1;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (instance->rised <= 0) {
- instance->rised = 0;
- if (time_out) {
- t = wait_event_interruptible_timeout(instance->
- wait_queue,
- (instance->rised !=
- 0), t);
-
- if (t == 0) {
- PERROR("Wait on interrupt timed out.\n");
- err = ME_ERRNO_TIMEOUT;
- }
- } else {
- wait_event_interruptible(instance->wait_queue,
- (instance->rised != 0));
- }
-
- if (instance->rised < 0) {
- PERROR("Wait on interrupt aborted by user.\n");
- err = ME_ERRNO_CANCELLED;
- }
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on interrupt aborted by signal.\n");
- err = ME_ERRNO_SIGNAL;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- instance->rised = 0;
- *irq_count = instance->n;
- *value = 1;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me1400_ext_irq_io_irq_stop(struct me_subdevice *subdevice,
- struct file *filep,
- int channel, int flags)
-{
- me1400_ext_irq_subdevice_t *instance;
- unsigned long cpu_flags;
- uint8_t tmp;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me1400_ext_irq_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- spin_lock(instance->clk_src_reg_lock);
-// // Disable IRQ on PLX
-// tmp = inb(instance->plx_intcs_reg) & ( ~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN));
-// outb(tmp, instance->plx_intcs_reg);
-// PDEBUG_REG("ctrl_reg outb(PLX:0x%lX)=0x%x\n", instance->plx_intcs_reg, tmp);
-
- switch (instance->device_id) {
- case PCI_DEVICE_ID_MEILHAUS_ME140C:
- case PCI_DEVICE_ID_MEILHAUS_ME140D:
- tmp = inb(instance->ctrl_reg);
- tmp &= ~ME1400CD_EXT_IRQ_CLK_EN;
- outb(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
-
- break;
-
- default:
- outb(0x00, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, 0x00);
- break;
- }
- spin_unlock(instance->clk_src_reg_lock);
- instance->rised = -1;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me1400_ext_irq_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me1400_ext_irq_subdevice_t *instance =
- (me1400_ext_irq_subdevice_t *) subdevice;
-
- PDEBUG("executed.\n");
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- instance->n = 0;
- return me1400_ext_irq_io_irq_stop(subdevice, filep, 0, flags);
-}
-
-static int me1400_ext_irq_query_number_channels(struct me_subdevice *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = ME1400_EXT_IRQ_NUMBER_CHANNELS;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1400_ext_irq_query_subdevice_type(struct me_subdevice *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_EXT_IRQ;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1400_ext_irq_query_subdevice_caps(struct me_subdevice *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_EXT_IRQ_EDGE_RISING;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1400_ext_irq_query_subdevice_caps_args(struct me_subdevice
- *subdevice, int cap,
- int *args, int count)
-{
- PDEBUG("executed.\n");
- return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id)
-{
- me1400_ext_irq_subdevice_t *instance;
- uint32_t status;
- uint8_t tmp;
-
- instance = (me1400_ext_irq_subdevice_t *) dev_id;
-
- if (irq != instance->irq) {
- PERROR("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- spin_lock(&instance->subdevice_lock);
- status = inl(instance->plx_intcs_reg);
-// if (!((status & PLX_LOCAL_INT1_STATE) && (status & PLX_LOCAL_INT1_EN) && (status & PLX_PCI_INT_EN)))
- if ((status &
- (PLX_LOCAL_INT1_STATE | PLX_LOCAL_INT1_EN | PLX_PCI_INT_EN)) !=
- (PLX_LOCAL_INT1_STATE | PLX_LOCAL_INT1_EN | PLX_PCI_INT_EN)) {
- spin_unlock(&instance->subdevice_lock);
- PINFO("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n",
- jiffies, __func__, status);
- return IRQ_NONE;
- }
-
- inl(instance->ctrl_reg);
-
- PDEBUG("executed.\n");
-
- instance->n++;
- instance->rised = 1;
-
- switch (instance->device_id) {
-
- case PCI_DEVICE_ID_MEILHAUS_ME140C:
- case PCI_DEVICE_ID_MEILHAUS_ME140D:
- spin_lock(instance->clk_src_reg_lock);
- tmp = inb(instance->ctrl_reg);
- tmp &= ~ME1400CD_EXT_IRQ_CLK_EN;
- outb(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- tmp |= ME1400CD_EXT_IRQ_CLK_EN;
- outb(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- spin_unlock(instance->clk_src_reg_lock);
-
- break;
-
- default:
- outb(0, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, 0);
- outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ME1400AB_EXT_IRQ_IRQ_EN);
- break;
- }
-
- spin_unlock(&instance->subdevice_lock);
- wake_up_interruptible_all(&instance->wait_queue);
-
- return IRQ_HANDLED;
-}
-
-static void me1400_ext_irq_destructor(struct me_subdevice *subdevice)
-{
- me1400_ext_irq_subdevice_t *instance;
- uint8_t tmp;
-
- PDEBUG("executed.\n");
-
- instance = (me1400_ext_irq_subdevice_t *) subdevice;
-
- // Disable IRQ on PLX
- tmp =
- inb(instance->
- plx_intcs_reg) & (~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL |
- PLX_PCI_INT_EN));
- outb(tmp, instance->plx_intcs_reg);
- PDEBUG_REG("ctrl_reg outb(plx:0x%lX)=0x%x\n", instance->plx_intcs_reg,
- tmp);
-
- free_irq(instance->irq, (void *)instance);
- me_subdevice_deinit(&instance->base);
- kfree(instance);
-}
-
-me1400_ext_irq_subdevice_t *me1400_ext_irq_constructor(uint32_t device_id,
- uint32_t plx_reg_base,
- uint32_t me1400_reg_base,
- spinlock_t *
- clk_src_reg_lock,
- int irq)
-{
- me1400_ext_irq_subdevice_t *subdevice;
- int err;
- uint8_t tmp;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me1400_ext_irq_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for 1400_ext_irq instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me1400_ext_irq_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
- subdevice->clk_src_reg_lock = clk_src_reg_lock;
-
- /* Initialize wait queue */
- init_waitqueue_head(&subdevice->wait_queue);
-
- subdevice->irq = irq;
-
- err = request_irq(irq, me1400_ext_irq_isr,
- IRQF_DISABLED | IRQF_SHARED,
- ME1400_NAME, (void *)subdevice);
-
- if (err) {
- PERROR("Can't get irq.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
- PINFO("Registered irq=%d.\n", subdevice->irq);
-
- /* Initialize registers */
- subdevice->plx_intcs_reg = plx_reg_base + PLX_INTCSR_REG;
- subdevice->ctrl_reg = me1400_reg_base + ME1400AB_EXT_IRQ_CTRL_REG;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = me1400_reg_base;
-#endif
-
- // Enable IRQ on PLX
- tmp =
- inb(subdevice->
- plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL |
- PLX_PCI_INT_EN);
- outb(tmp, subdevice->plx_intcs_reg);
- PDEBUG_REG("ctrl_reg outb(Pplx:0x%lX)=0x%x\n", subdevice->plx_intcs_reg,
- tmp);
-
- /* Initialize the subdevice methods */
- subdevice->base.me_subdevice_io_irq_start = me1400_ext_irq_io_irq_start;
- subdevice->base.me_subdevice_io_irq_wait = me1400_ext_irq_io_irq_wait;
- subdevice->base.me_subdevice_io_irq_stop = me1400_ext_irq_io_irq_stop;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me1400_ext_irq_io_reset_subdevice;
- subdevice->base.me_subdevice_query_number_channels =
- me1400_ext_irq_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me1400_ext_irq_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me1400_ext_irq_query_subdevice_caps;
- subdevice->base.me_subdevice_query_subdevice_caps_args =
- me1400_ext_irq_query_subdevice_caps_args;
- subdevice->base.me_subdevice_destructor = me1400_ext_irq_destructor;
-
- subdevice->rised = 0;
- subdevice->n = 0;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me1400_ext_irq.h b/drivers/staging/meilhaus/me1400_ext_irq.h
deleted file mode 100644
index 9b72a04..0000000
--- a/drivers/staging/meilhaus/me1400_ext_irq.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file me1400_ext_irq.h
- *
- * @brief ME-1400 external interrupt implementation.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME1400_EXT_IRQ_H_
-#define _ME1400_EXT_IRQ_H_
-
-#include <linux/sched.h>
-
-#include "mesubdevice.h"
-#include "meslock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The ME-1400 external interrupt subdevice class.
- */
-typedef struct me1400_ext_irq_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *clk_src_reg_lock; /**< Lock protecting the clock control register. */
-
- wait_queue_head_t wait_queue; /**< Queue to put on threads waiting for an interrupt. */
-
- uint32_t device_id; /**< The device id of the device holding the subdevice. */
- int irq; /**< The irq number assigned by PCI BIOS. */
- int rised; /**< If true an interrupt has occured. */
- unsigned int n; /**< The number of interrupt since the driver was loaded. */
-
- unsigned long plx_intcs_reg; /**< The PLX interrupt control and status register. */
- unsigned long ctrl_reg; /**< The control register. */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me1400_ext_irq_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-1400 external interrupt instance.
- *
- * @param plx_reg_base The register base address of the PLX chip as returned by the PCI BIOS.
- * @param me1400_reg_base The register base address of the ME-1400 device as returned by the PCI BIOS.
- * @param irq The irq assigned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me1400_ext_irq_subdevice_t *me1400_ext_irq_constructor(uint32_t device_id,
- uint32_t plx_reg_base,
- uint32_t me1400_reg_base,
- spinlock_t *
- clk_src_reg_lock,
- int irq);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1400_ext_irq_reg.h b/drivers/staging/meilhaus/me1400_ext_irq_reg.h
deleted file mode 100644
index c9740f2..0000000
--- a/drivers/staging/meilhaus/me1400_ext_irq_reg.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @file me1400_ext_irq_reg.h
- *
- * @brief ME-1400 external interrupt register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME1400_EXT_IRQ_REG_H_
-# define _ME1400_EXT_IRQ_REG_H_
-
-# ifdef __KERNEL__
-
-# define PLX_INTCSR_REG 0x4C /**< The PLX interrupt control and status register offset. */
-# define PLX_ICR_REG 0x50 /**< The PLX initialization control register offset. */
-
-# define PLX_LOCAL_INT1_EN 0x01 /**< If set the local interrupt 1 is enabled. */
-# define PLX_LOCAL_INT1_POL 0x02 /**< If set the local interrupt 1 polarity is high active. */
-# define PLX_LOCAL_INT1_STATE 0x04 /**< If set the local interrupt 1 is activ. */
-# define PLX_LOCAL_INT2_EN 0x08 /**< If set the local interrupt 2 is enabled. */
-# define PLX_LOCAL_INT2_POL 0x10 /**< If set the local interrupt 2 polarity is high active. */
-# define PLX_LOCAL_INT2_STATE 0x20 /**< If set the local interrupt 2 is activ. */
-# define PLX_PCI_INT_EN 0x40 /**< If set the PCI interrupt is enabled. */
-# define PLX_SOFT_INT 0x80 /**< If set an interrupt is generated. */
-
-# define ME1400AB_EXT_IRQ_CTRL_REG 0x11 /**< The external interrupt control register offset. */
-
-# define ME1400AB_EXT_IRQ_CLK_EN 0x01 /**< If this bit is set, the clock output is enabled. */
-# define ME1400AB_EXT_IRQ_IRQ_EN 0x02 /**< If set the external interrupt is enabled. Clearing this bit clears a pending interrupt. */
-
-# define ME1400CD_EXT_IRQ_CTRL_REG 0x11 /**< The external interrupt control register offset. */
-
-# define ME1400CD_EXT_IRQ_CLK_EN 0x10 /**< If set the external interrupt is enabled. Clearing this bit clears a pending interrupt.*/
-
-# endif //__KERNEL__
-
-#endif //_ME1400_EXT_IRQ_REG_H_
diff --git a/drivers/staging/meilhaus/me1600_ao.c b/drivers/staging/meilhaus/me1600_ao.c
deleted file mode 100644
index 12e3c70..0000000
--- a/drivers/staging/meilhaus/me1600_ao.c
+++ /dev/null
@@ -1,1017 +0,0 @@
-/**
- * @file me1600_ao.c
- *
- * @brief ME-1600 analog output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/* Includes
- */
-
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-
-#include <linux/workqueue.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "medebug.h"
-
-#include "me1600_ao_reg.h"
-#include "me1600_ao.h"
-
-/* Defines
- */
-
-static void me1600_ao_destructor(struct me_subdevice *subdevice);
-
-static void me1600_ao_work_control_task(struct work_struct *work);
-
-static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
- struct file *filep, int flags);
-static int me1600_ao_io_single_config(me_subdevice_t *subdevice,
- struct file *filep, int channel,
- int single_config, int ref, int trig_chan,
- int trig_type, int trig_edge, int flags);
-static int me1600_ao_io_single_read(me_subdevice_t *subdevice,
- struct file *filep, int channel, int *value,
- int time_out, int flags);
-static int me1600_ao_io_single_write(me_subdevice_t *subdevice,
- struct file *filep, int channel, int value,
- int time_out, int flags);
-static int me1600_ao_query_number_channels(me_subdevice_t *subdevice,
- int *number);
-static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type,
- int *subtype);
-static int me1600_ao_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps);
-static int me1600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
- int unit, int *min, int *max,
- int *maxdata, int *range);
-static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice, int unit,
- int *count);
-static int me1600_ao_query_range_info(me_subdevice_t *subdevice, int range,
- int *unit, int *min, int *max,
- int *maxdata);
-
-/* Functions
- */
-
-me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base,
- unsigned int ao_idx,
- int curr,
- spinlock_t *config_regs_lock,
- spinlock_t *ao_shadows_lock,
- me1600_ao_shadow_t *ao_regs_shadows,
- struct workqueue_struct *me1600_wq)
-{
- me1600_ao_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed. idx=%d\n", ao_idx);
-
- // Allocate memory for subdevice instance.
- subdevice = kmalloc(sizeof(me1600_ao_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR
- ("Cannot get memory for analog output subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me1600_ao_subdevice_t));
-
- // Initialize subdevice base class.
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
- subdevice->config_regs_lock = config_regs_lock;
- subdevice->ao_shadows_lock = ao_shadows_lock;
-
- // Save the subdevice index.
- subdevice->ao_idx = ao_idx;
-
- // Initialize range lists.
- subdevice->u_ranges_count = 2;
-
- subdevice->u_ranges[0].min = 0; //0V
- subdevice->u_ranges[0].max = 9997558; //10V
-
- subdevice->u_ranges[1].min = -10E6; //-10V
- subdevice->u_ranges[1].max = 9995117; //10V
-
- if (curr) { // This is version with current outputs.
- subdevice->i_ranges_count = 2;
-
- subdevice->i_ranges[0].min = 0; //0mA
- subdevice->i_ranges[0].max = 19995117; //20mA
-
- subdevice->i_ranges[1].min = 4E3; //4mA
- subdevice->i_ranges[1].max = 19995118; //20mA
- } else { // This is version without current outputs.
- subdevice->i_ranges_count = 0;
-
- subdevice->i_ranges[0].min = 0; //0mA
- subdevice->i_ranges[0].max = 0; //0mA
-
- subdevice->i_ranges[1].min = 0; //0mA
- subdevice->i_ranges[1].max = 0; //0mA
- }
-
- // Initialize registers.
- subdevice->uni_bi_reg = reg_base + ME1600_UNI_BI_REG;
- subdevice->i_range_reg = reg_base + ME1600_020_420_REG;
- subdevice->sim_output_reg = reg_base + ME1600_SIM_OUTPUT_REG;
- subdevice->current_on_reg = reg_base + ME1600_CURRENT_ON_REG;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- // Initialize shadow structure.
- subdevice->ao_regs_shadows = ao_regs_shadows;
-
- // Override base class methods.
- subdevice->base.me_subdevice_destructor = me1600_ao_destructor;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me1600_ao_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me1600_ao_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me1600_ao_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me1600_ao_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me1600_ao_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me1600_ao_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me1600_ao_query_subdevice_caps;
- subdevice->base.me_subdevice_query_range_by_min_max =
- me1600_ao_query_range_by_min_max;
- subdevice->base.me_subdevice_query_number_ranges =
- me1600_ao_query_number_ranges;
- subdevice->base.me_subdevice_query_range_info =
- me1600_ao_query_range_info;
-
- // Initialize wait queue.
- init_waitqueue_head(&subdevice->wait_queue);
-
- // Prepare work queue.
- subdevice->me1600_workqueue = me1600_wq;
-
-/* workqueue API changed in kernel 2.6.20 */
- INIT_DELAYED_WORK(&subdevice->ao_control_task,
- me1600_ao_work_control_task);
- return subdevice;
-}
-
-static void me1600_ao_destructor(struct me_subdevice *subdevice)
-{
- me1600_ao_subdevice_t *instance;
-
- instance = (me1600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- instance->ao_control_task_flag = 0;
-
- // Reset subdevice to asure clean exit.
- me1600_ao_io_reset_subdevice(subdevice, NULL,
- ME_IO_RESET_SUBDEVICE_NO_FLAGS);
-
- // Remove any tasks from work queue. This is paranoic because it was done allready in reset().
- if (!cancel_delayed_work(&instance->ao_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue.
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(2);
- }
-}
-
-static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
- struct file *filep, int flags)
-{
- me1600_ao_subdevice_t *instance;
- uint16_t tmp;
-
- instance = (me1600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- //Cancel control task
- PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
- (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Cancell waiting for trigger.
-
- // Reset all settings.
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ao_shadows_lock);
- (instance->ao_regs_shadows)->shadow[instance->ao_idx] = 0;
- (instance->ao_regs_shadows)->mirror[instance->ao_idx] = 0;
- (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Not waiting for triggering.
- (instance->ao_regs_shadows)->synchronous &= ~(0x1 << instance->ao_idx); //Individual triggering.
-
- // Set output to default (safe) state.
- spin_lock(instance->config_regs_lock);
- tmp = inw(instance->uni_bi_reg); // unipolar
- tmp |= (0x1 << instance->ao_idx);
- outw(tmp, instance->uni_bi_reg);
- PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->uni_bi_reg - instance->reg_base, tmp);
-
- tmp = inw(instance->current_on_reg); // Volts only!
- tmp &= ~(0x1 << instance->ao_idx);
- tmp &= 0x00FF;
- outw(tmp, instance->current_on_reg);
- PDEBUG_REG("current_on_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->current_on_reg - instance->reg_base, tmp);
-
- tmp = inw(instance->i_range_reg); // 0..20mA <= If exists.
- tmp &= ~(0x1 << instance->ao_idx);
- outw(tmp, instance->i_range_reg);
- PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->i_range_reg - instance->reg_base, tmp);
-
- outw(0, (instance->ao_regs_shadows)->registry[instance->ao_idx]);
- PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- (instance->ao_regs_shadows)->registry[instance->ao_idx] -
- instance->reg_base, 0);
-
- // Trigger output.
- outw(0x0000, instance->sim_output_reg);
- PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sim_output_reg - instance->reg_base, 0x0000);
- outw(0xFFFF, instance->sim_output_reg);
- PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sim_output_reg - instance->reg_base, 0xFFFF);
- spin_unlock(instance->config_regs_lock);
- spin_unlock(instance->ao_shadows_lock);
-
- // Set status to 'none'
- instance->status = ao_status_none;
- spin_unlock(&instance->subdevice_lock);
-
- //Signal reset if user is on wait.
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me1600_ao_subdevice_t *instance;
- uint16_t tmp;
-
- instance = (me1600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- // Checking parameters.
- if (flags) {
- PERROR
- ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (trig_edge != ME_TRIG_EDGE_NONE) {
- PERROR
- ("Invalid trigger edge. Software trigger has not edge. Must be ME_TRIG_EDGE_NONE\n");
- return ME_ERRNO_INVALID_TRIG_EDGE;
- }
-
- if (trig_type != ME_TRIG_TYPE_SW) {
- PERROR("Invalid trigger edge. Must be ME_TRIG_TYPE_SW.\n");
- return ME_ERRNO_INVALID_TRIG_TYPE;
- }
-
- if ((trig_chan != ME_TRIG_CHAN_DEFAULT)
- && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) {
- PERROR("Invalid trigger channel specified.\n");
- return ME_ERRNO_INVALID_TRIG_CHAN;
- }
-
- if (ref != ME_REF_AO_GROUND) {
- PERROR
- ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n");
- return ME_ERRNO_INVALID_REF;
- }
-
- if (((single_config + 1) >
- (instance->u_ranges_count + instance->i_ranges_count))
- || (single_config < 0)) {
- PERROR("Invalid range specified.\n");
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
- // Checking parameters - done. All is fine. Do config.
-
- ME_SUBDEVICE_ENTER;
-
- //Cancel control task
- PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ao_shadows_lock);
- (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Cancell waiting for trigger.
- (instance->ao_regs_shadows)->shadow[instance->ao_idx] = 0;
- (instance->ao_regs_shadows)->mirror[instance->ao_idx] = 0;
-
- spin_lock(instance->config_regs_lock);
- switch (single_config) {
- case 0: // 0V 10V
- tmp = inw(instance->current_on_reg); // Volts
- tmp &= ~(0x1 << instance->ao_idx);
- outw(tmp, instance->current_on_reg);
- PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->current_on_reg - instance->reg_base, tmp);
-
- // 0V
- outw(0,
- (instance->ao_regs_shadows)->registry[instance->ao_idx]);
- PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- (instance->ao_regs_shadows)->registry[instance->
- ao_idx] -
- instance->reg_base, 0);
-
- tmp = inw(instance->uni_bi_reg); // unipolar
- tmp |= (0x1 << instance->ao_idx);
- outw(tmp, instance->uni_bi_reg);
- PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->uni_bi_reg - instance->reg_base, tmp);
-
- tmp = inw(instance->i_range_reg); // 0..20mA <= If exists.
- tmp &= ~(0x1 << instance->ao_idx);
- outw(tmp, instance->i_range_reg);
- PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->i_range_reg - instance->reg_base, tmp);
- break;
-
- case 1: // -10V 10V
- tmp = inw(instance->current_on_reg); // Volts
- tmp &= ~(0x1 << instance->ao_idx);
- outw(tmp, instance->current_on_reg);
- PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->current_on_reg - instance->reg_base, tmp);
-
- // 0V
- outw(0x0800,
- (instance->ao_regs_shadows)->registry[instance->ao_idx]);
- PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- (instance->ao_regs_shadows)->registry[instance->
- ao_idx] -
- instance->reg_base, 0x0800);
-
- tmp = inw(instance->uni_bi_reg); // bipolar
- tmp &= ~(0x1 << instance->ao_idx);
- outw(tmp, instance->uni_bi_reg);
- PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->uni_bi_reg - instance->reg_base, tmp);
-
- tmp = inw(instance->i_range_reg); // 0..20mA <= If exists.
- tmp &= ~(0x1 << instance->ao_idx);
- outw(tmp, instance->i_range_reg);
- PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->i_range_reg - instance->reg_base, tmp);
- break;
-
- case 2: // 0mA 20mA
- tmp = inw(instance->current_on_reg); // mAmpers
- tmp |= (0x1 << instance->ao_idx);
- outw(tmp, instance->current_on_reg);
- PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->current_on_reg - instance->reg_base, tmp);
-
- tmp = inw(instance->i_range_reg); // 0..20mA
- tmp &= ~(0x1 << instance->ao_idx);
- outw(tmp, instance->i_range_reg);
- PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->i_range_reg - instance->reg_base, tmp);
-
- // 0mA
- outw(0,
- (instance->ao_regs_shadows)->registry[instance->ao_idx]);
- PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- (instance->ao_regs_shadows)->registry[instance->
- ao_idx] -
- instance->reg_base, 0);
-
- tmp = inw(instance->uni_bi_reg); // unipolar
- tmp |= (0x1 << instance->ao_idx);
- outw(tmp, instance->uni_bi_reg);
- PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->uni_bi_reg - instance->reg_base, tmp);
- break;
-
- case 3: // 4mA 20mA
- tmp = inw(instance->current_on_reg); // mAmpers
- tmp |= (0x1 << instance->ao_idx);
- outw(tmp, instance->current_on_reg);
- PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->current_on_reg - instance->reg_base, tmp);
-
- tmp = inw(instance->i_range_reg); // 4..20mA
- tmp |= (0x1 << instance->ao_idx);
- outw(tmp, instance->i_range_reg);
- PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->i_range_reg - instance->reg_base, tmp);
-
- // 4mA
- outw(0,
- (instance->ao_regs_shadows)->registry[instance->ao_idx]);
- PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- (instance->ao_regs_shadows)->registry[instance->
- ao_idx] -
- instance->reg_base, 0);
-
- tmp = inw(instance->uni_bi_reg); // unipolar
- tmp |= (0x1 << instance->ao_idx);
- outw(tmp, instance->uni_bi_reg);
- PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->uni_bi_reg - instance->reg_base, tmp);
- break;
- }
-
- // Trigger output.
- outw(0x0000, instance->sim_output_reg);
- PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sim_output_reg - instance->reg_base, 0x0000);
- outw(0xFFFF, instance->sim_output_reg);
- PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sim_output_reg - instance->reg_base, 0xFFFF);
-
- if (trig_chan == ME_TRIG_CHAN_DEFAULT) { // Individual triggering.
- (instance->ao_regs_shadows)->synchronous &=
- ~(0x1 << instance->ao_idx);
- PDEBUG("Individual triggering.\n");
- } else if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS) { // Synchronous triggering.
- (instance->ao_regs_shadows)->synchronous |=
- (0x1 << instance->ao_idx);
- PDEBUG("Synchronous triggering.\n");
- }
- spin_unlock(instance->config_regs_lock);
- spin_unlock(instance->ao_shadows_lock);
-
- instance->status = ao_status_single_configured;
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me1600_ao_subdevice_t *instance;
- unsigned long delay = 0;
- unsigned long j = 0;
- int err = ME_ERRNO_SUCCESS;
-
- instance = (me1600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags & ~ME_IO_SINGLE_NONBLOCKING) {
- PERROR("Invalid flag specified. %d\n", flags);
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if ((!flags) && ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) { //Blocking mode. Wait for software trigger.
- if (time_out) {
- delay = (time_out * HZ) / 1000;
- if (delay == 0)
- delay = 1;
- }
-
- j = jiffies;
-
- //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
- wait_event_interruptible_timeout(instance->wait_queue,
- (!((instance->
- ao_regs_shadows)->
- trigger & instance->
- ao_idx)),
- (delay) ? delay : LONG_MAX);
-
- if (instance == ao_status_none) { // Reset was called.
- PDEBUG("Single canceled.\n");
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on start of state machine interrupted.\n");
- err = ME_ERRNO_SIGNAL;
- }
-
- if ((delay) && ((jiffies - j) >= delay)) {
- PDEBUG("Timeout reached.\n");
- err = ME_ERRNO_TIMEOUT;
- }
- }
-
- *value = (instance->ao_regs_shadows)->mirror[instance->ao_idx];
-
- return err;
-}
-
-static int me1600_ao_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me1600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long delay = 0;
- int i;
- unsigned long j = 0;
-
- instance = (me1600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags &
- ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS |
- ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (value & ~ME1600_AO_MAX_DATA) {
- PERROR("Invalid value provided.\n");
- return ME_ERRNO_VALUE_OUT_OF_RANGE;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- //Cancel control task
- PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
- (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Cancell waiting for trigger.
-
- if (time_out) {
- delay = (time_out * HZ) / 1000;
-
- if (delay == 0)
- delay = 1;
- }
- //Write value.
- spin_lock(instance->ao_shadows_lock);
- (instance->ao_regs_shadows)->shadow[instance->ao_idx] =
- (uint16_t) value;
-
- if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { // Trigger all outputs from synchronous list.
- for (i = 0; i < (instance->ao_regs_shadows)->count; i++) {
- if (((instance->ao_regs_shadows)->synchronous & (0x1 << i)) || (i == instance->ao_idx)) { // Set all from synchronous list to correct state.
- PDEBUG
- ("Synchronous triggering: output %d. idx=%d\n",
- i, instance->ao_idx);
- (instance->ao_regs_shadows)->mirror[i] =
- (instance->ao_regs_shadows)->shadow[i];
-
- outw((instance->ao_regs_shadows)->shadow[i],
- (instance->ao_regs_shadows)->registry[i]);
- PDEBUG_REG
- ("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- (instance->ao_regs_shadows)->registry[i] -
- instance->reg_base,
- (instance->ao_regs_shadows)->shadow[i]);
-
- (instance->ao_regs_shadows)->trigger &=
- ~(0x1 << i);
- }
- }
-
- // Trigger output.
- outw(0x0000, instance->sim_output_reg);
- PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sim_output_reg - instance->reg_base, 0);
- outw(0xFFFF, instance->sim_output_reg);
- PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sim_output_reg - instance->reg_base,
- 0xFFFF);
- instance->status = ao_status_single_end;
- } else { // Individual mode.
- if ((instance->ao_regs_shadows)->synchronous & (0x1 << instance->ao_idx)) { // Put on synchronous start list. Set output as waiting for trigger.
- PDEBUG("Add to synchronous list. idx=%d\n",
- instance->ao_idx);
- (instance->ao_regs_shadows)->trigger |=
- (0x1 << instance->ao_idx);
- instance->status = ao_status_single_run;
- PDEBUG("Synchronous list: 0x%x.\n",
- (instance->ao_regs_shadows)->synchronous);
- } else { // Fired this one.
- PDEBUG("Triggering. idx=%d\n", instance->ao_idx);
- (instance->ao_regs_shadows)->mirror[instance->ao_idx] =
- (instance->ao_regs_shadows)->shadow[instance->
- ao_idx];
-
- outw((instance->ao_regs_shadows)->
- shadow[instance->ao_idx],
- (instance->ao_regs_shadows)->registry[instance->
- ao_idx]);
- PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- (instance->ao_regs_shadows)->
- registry[instance->ao_idx] -
- instance->reg_base,
- (instance->ao_regs_shadows)->
- shadow[instance->ao_idx]);
-
- // Set output as triggered.
- (instance->ao_regs_shadows)->trigger &=
- ~(0x1 << instance->ao_idx);
-
- // Trigger output.
- outw(0x0000, instance->sim_output_reg);
- PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sim_output_reg -
- instance->reg_base, 0);
- outw(0xFFFF, instance->sim_output_reg);
- PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sim_output_reg -
- instance->reg_base, 0xFFFF);
- instance->status = ao_status_single_end;
- }
- }
- spin_unlock(instance->ao_shadows_lock);
-
- //Init control task
- instance->timeout.delay = delay;
- instance->timeout.start_time = jiffies;
- instance->ao_control_task_flag = 1;
- queue_delayed_work(instance->me1600_workqueue,
- &instance->ao_control_task, 1);
-
- if ((!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) &&
- ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) {
- /* Blocking mode. Wait for software trigger. */
- if (time_out) {
- delay = (time_out * HZ) / 1000;
- if (delay == 0)
- delay = 1;
- }
-
- j = jiffies;
-
- //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
- wait_event_interruptible_timeout(instance->wait_queue,
- (!((instance->
- ao_regs_shadows)->
- trigger & instance->
- ao_idx)),
- (delay) ? delay : LONG_MAX);
-
- if (instance == ao_status_none) {
- PDEBUG("Single canceled.\n");
- err = ME_ERRNO_CANCELLED;
- }
- if (signal_pending(current)) {
- PERROR("Wait on start of state machine interrupted.\n");
- err = ME_ERRNO_SIGNAL;
- }
-
- if ((delay) && ((jiffies - j) >= delay)) {
- PDEBUG("Timeout reached.\n");
- err = ME_ERRNO_TIMEOUT;
- }
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me1600_ao_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- me1600_ao_subdevice_t *instance;
- instance = (me1600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- *number = 1; //Every subdevice has only 1 channel.
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type,
- int *subtype)
-{
- me1600_ao_subdevice_t *instance;
- instance = (me1600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- *type = ME_TYPE_AO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_AO_TRIG_SYNCHRONOUS;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
- int unit,
- int *min,
- int *max, int *maxdata, int *range)
-{
- me1600_ao_subdevice_t *instance;
- int i;
- int r = -1;
- int diff = 21E6;
-
- instance = (me1600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if ((*max - *min) < 0) {
- PERROR("Invalid minimum and maximum values specified.\n");
- return ME_ERRNO_INVALID_MIN_MAX;
- }
- // Maximum ranges are slightly less then 10V or 20mA. For convenient we accepted this value as valid one.
- if (unit == ME_UNIT_VOLT) {
- for (i = 0; i < instance->u_ranges_count; i++) {
- if ((instance->u_ranges[i].min <= *min)
- && ((instance->u_ranges[i].max + 5000) >= *max)) {
- if ((instance->u_ranges[i].max -
- instance->u_ranges[i].min) - (*max -
- *min) <
- diff) {
- r = i;
- diff =
- (instance->u_ranges[i].max -
- instance->u_ranges[i].min) -
- (*max - *min);
- }
- }
- }
-
- if (r < 0) {
- PERROR("No matching range found.\n");
- return ME_ERRNO_NO_RANGE;
- } else {
- *min = instance->u_ranges[r].min;
- *max = instance->u_ranges[r].max;
- *range = r;
- }
- } else if (unit == ME_UNIT_AMPERE) {
- for (i = 0; i < instance->i_ranges_count; i++) {
- if ((instance->i_ranges[i].min <= *min)
- && (instance->i_ranges[i].max + 5000 >= *max)) {
- if ((instance->i_ranges[i].max -
- instance->i_ranges[i].min) - (*max -
- *min) <
- diff) {
- r = i;
- diff =
- (instance->i_ranges[i].max -
- instance->i_ranges[i].min) -
- (*max - *min);
- }
- }
- }
-
- if (r < 0) {
- PERROR("No matching range found.\n");
- return ME_ERRNO_NO_RANGE;
- } else {
- *min = instance->i_ranges[r].min;
- *max = instance->i_ranges[r].max;
- *range = r + instance->u_ranges_count;
- }
- } else {
- PERROR("Invalid physical unit specified.\n");
- return ME_ERRNO_INVALID_UNIT;
- }
- *maxdata = ME1600_AO_MAX_DATA;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice,
- int unit, int *count)
-{
- me1600_ao_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me1600_ao_subdevice_t *) subdevice;
- switch (unit) {
- case ME_UNIT_VOLT:
- *count = instance->u_ranges_count;
- break;
- case ME_UNIT_AMPERE:
- *count = instance->i_ranges_count;
- break;
- case ME_UNIT_ANY:
- *count = instance->u_ranges_count + instance->i_ranges_count;
- break;
- default:
- *count = 0;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_query_range_info(me_subdevice_t *subdevice,
- int range,
- int *unit,
- int *min, int *max, int *maxdata)
-{
- me1600_ao_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me1600_ao_subdevice_t *) subdevice;
-
- if (((range + 1) >
- (instance->u_ranges_count + instance->i_ranges_count))
- || (range < 0)) {
- PERROR("Invalid range number specified.\n");
- return ME_ERRNO_INVALID_RANGE;
- }
-
- if (range < instance->u_ranges_count) {
- *unit = ME_UNIT_VOLT;
- *min = instance->u_ranges[range].min;
- *max = instance->u_ranges[range].max;
- } else if (range < instance->u_ranges_count + instance->i_ranges_count) {
- *unit = ME_UNIT_AMPERE;
- *min = instance->i_ranges[range - instance->u_ranges_count].min;
- *max = instance->i_ranges[range - instance->u_ranges_count].max;
- }
- *maxdata = ME1600_AO_MAX_DATA;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static void me1600_ao_work_control_task(struct work_struct *work)
-{
- me1600_ao_subdevice_t *instance;
- int reschedule = 1;
- int signaling = 0;
-
- instance =
- container_of((void *)work, me1600_ao_subdevice_t, ao_control_task);
-
- PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
- instance->ao_idx);
-
- if (!((instance->ao_regs_shadows)->trigger & instance->ao_idx)) { // Output was triggerd.
- // Signal the end.
- signaling = 1;
- reschedule = 0;
- if (instance->status == ao_status_single_run) {
- instance->status = ao_status_single_end;
- }
-
- } else if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
- PDEBUG("Timeout reached.\n");
- spin_lock(instance->ao_shadows_lock);
- // Restore old settings.
- PDEBUG("Write old value back to register.\n");
- (instance->ao_regs_shadows)->shadow[instance->ao_idx] =
- (instance->ao_regs_shadows)->mirror[instance->ao_idx];
-
- outw((instance->ao_regs_shadows)->mirror[instance->ao_idx],
- (instance->ao_regs_shadows)->registry[instance->ao_idx]);
- PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- (instance->ao_regs_shadows)->registry[instance->
- ao_idx] -
- instance->reg_base,
- (instance->ao_regs_shadows)->mirror[instance->
- ao_idx]);
-
- //Remove from synchronous strt list.
- (instance->ao_regs_shadows)->trigger &=
- ~(0x1 << instance->ao_idx);
- if (instance->status == ao_status_none) {
- instance->status = ao_status_single_end;
- }
- spin_unlock(instance->ao_shadows_lock);
-
- // Signal the end.
- signaling = 1;
- reschedule = 0;
- }
-
- if (signaling) { //Signal it.
- wake_up_interruptible_all(&instance->wait_queue);
- }
-
- if (instance->ao_control_task_flag && reschedule) { // Reschedule task
- queue_delayed_work(instance->me1600_workqueue,
- &instance->ao_control_task, 1);
- } else {
- PINFO("<%s> Ending control task.\n", __func__);
- }
-
-}
diff --git a/drivers/staging/meilhaus/me1600_ao.h b/drivers/staging/meilhaus/me1600_ao.h
deleted file mode 100644
index 4827dcb..0000000
--- a/drivers/staging/meilhaus/me1600_ao.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * @file me1600_ao.h
- *
- * @brief Meilhaus ME-1600 analog output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME1600_AO_H_
-#define _ME1600_AO_H_
-
-# include <linux/version.h>
-# include "mesubdevice.h"
-
-# ifdef __KERNEL__
-
-# 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. */
-
-/**
- * @brief Defines a entry in the range table.
- */
-typedef struct me1600_ao_range_entry {
- int32_t min;
- int32_t max;
-} me1600_ao_range_entry_t;
-
-typedef struct me1600_ao_timeout {
- unsigned long start_time;
- unsigned long delay;
-} me1600_ao_timeout_t;
-
-typedef struct me1600_ao_shadow {
- int count;
- unsigned long *registry;
- uint16_t *shadow;
- uint16_t *mirror;
- uint16_t synchronous; /**< Synchronization list. */
- uint16_t trigger; /**< Synchronization flag. */
-} me1600_ao_shadow_t;
-
-typedef enum ME1600_AO_STATUS {
- ao_status_none = 0,
- ao_status_single_configured,
- ao_status_single_run,
- ao_status_single_end,
- ao_status_last
-} ME1600_AO_STATUS;
-
-/**
- * @brief The ME-1600 analog output subdevice class.
- */
-typedef struct me1600_ao_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- int ao_idx; /**< The index of the analog output subdevice on the device. */
-
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *config_regs_lock; /**< Spin lock to protect configuration registers from concurrent access. */
-
- int u_ranges_count; /**< The number of voltage ranges available on this subdevice. */
- me1600_ao_range_entry_t u_ranges[ME1600_MAX_RANGES]; /**< Array holding the voltage ranges on this subdevice. */
- int i_ranges_count; /**< The number of current ranges available on this subdevice. */
- me1600_ao_range_entry_t i_ranges[ME1600_MAX_RANGES]; /**< Array holding the current ranges on this subdevice. */
-
- /* Registers */
- unsigned long uni_bi_reg; /**< Register for switching between unipoar and bipolar output mode. */
- unsigned long i_range_reg; /**< Register for switching between ranges. */
- unsigned long sim_output_reg; /**< Register used in order to update all channels simultaneously. */
- unsigned long current_on_reg; /**< Register enabling current output on the fourth subdevice. */
-# ifdef PDEBUG_REG
- unsigned long reg_base;
-# endif
-
- ME1600_AO_STATUS status;
- me1600_ao_shadow_t *ao_regs_shadows; /**< Addresses and shadows of output's registers. */
- spinlock_t *ao_shadows_lock; /**< Protects the shadow's struct. */
- int mode; /**< Mode in witch output should works. */
- wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
- me1600_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
- struct workqueue_struct *me1600_workqueue;
- struct delayed_work ao_control_task;
-
- volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
-} me1600_ao_subdevice_t;
-
-/**
- * @brief The constructor to generate a subdevice template instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param ao_idx The index of the analog output subdevice on the device.
- * @param current Flag indicating that analog output with #ao_idx of 3 is capable of current output.
- * @param config_regs_lock Pointer to spin lock protecting the configuration registers and from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base,
- unsigned int ao_idx,
- int curr,
- spinlock_t * config_regs_lock,
- spinlock_t * ao_shadows_lock,
- me1600_ao_shadow_t *
- ao_regs_shadows,
- struct workqueue_struct
- *me1600_wq);
-
-# endif //__KERNEL__
-#endif //_ME1600_AO_H_
diff --git a/drivers/staging/meilhaus/me1600_ao_reg.h b/drivers/staging/meilhaus/me1600_ao_reg.h
deleted file mode 100644
index 31e7800..0000000
--- a/drivers/staging/meilhaus/me1600_ao_reg.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file me1600_ao_reg.h
- *
- * @brief ME-1600 analog output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME1600_AO_REG_H_
-#define _ME1600_AO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME1600_CHANNEL_0_REG 0x00 /**< Register to set a digital value on channel 0. */
-#define ME1600_CHANNEL_1_REG 0x02 /**< Register to set a digital value on channel 1. */
-#define ME1600_CHANNEL_2_REG 0x04 /**< Register to set a digital value on channel 2. */
-#define ME1600_CHANNEL_3_REG 0x06 /**< Register to set a digital value on channel 3. */
-#define ME1600_CHANNEL_4_REG 0x08 /**< Register to set a digital value on channel 4. */
-#define ME1600_CHANNEL_5_REG 0x0A /**< Register to set a digital value on channel 5. */
-#define ME1600_CHANNEL_6_REG 0x0C /**< Register to set a digital value on channel 6. */
-#define ME1600_CHANNEL_7_REG 0x0E /**< Register to set a digital value on channel 7. */
-#define ME1600_CHANNEL_8_REG 0x10 /**< Register to set a digital value on channel 8. */
-#define ME1600_CHANNEL_9_REG 0x12 /**< Register to set a digital value on channel 9. */
-#define ME1600_CHANNEL_10_REG 0x14 /**< Register to set a digital value on channel 10. */
-#define ME1600_CHANNEL_11_REG 0x16 /**< Register to set a digital value on channel 11. */
-#define ME1600_CHANNEL_12_REG 0x18 /**< Register to set a digital value on channel 12. */
-#define ME1600_CHANNEL_13_REG 0x1A /**< Register to set a digital value on channel 13. */
-#define ME1600_CHANNEL_14_REG 0x1C /**< Register to set a digital value on channel 14. */
-#define ME1600_CHANNEL_15_REG 0x1E /**< Register to set a digital value on channel 15. */
-
-/* Every channel one bit: bipolar = 0, unipolar = 1 */
-#define ME1600_UNI_BI_REG 0x20 /**< Register to switch between unipolar and bipolar. */
-
-/* Every channel one bit (only lower 8 Bits): 0..20mA = 0, 4..20mA = 1 */
-#define ME1600_020_420_REG 0x22 /**< Register to switch between the two current ranges. */
-
-/* If a bit is set, the corresponding DAC (4 ports each) is
- not set at the moment you write to an output of it.
- Clearing the bit updates the port. */
-#define ME1600_SIM_OUTPUT_REG 0x24 /**< Register to update all channels of a subdevice simultaneously. */
-
-/* Current on/off (only lower 8 bits): off = 0, on = 1 */
-#define ME1600_CURRENT_ON_REG 0x26 /**< Register to swicht between voltage and current output. */
-
-#define ME1600_AO_MAX_DATA 0x0FFF /**< The maximum digital data accepted by an analog output channel. */
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1600_device.c b/drivers/staging/meilhaus/me1600_device.c
deleted file mode 100644
index c244e98..0000000
--- a/drivers/staging/meilhaus/me1600_device.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/**
- * @file me1600_device.c
- *
- * @brief ME-1600 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#ifndef MODULE
-# define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "mesubdevice.h"
-#include "me1600_device.h"
-
-static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base);
-static void me1600_destructor(struct me_device *device);
-
-/**
- * @brief Global variable.
- * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts).
- */
-static struct workqueue_struct *me1600_workqueue;
-
-me_device_t *me1600_pci_constructor(struct pci_dev *pci_device)
-{
- int err;
- me1600_device_t *me1600_device;
- me_subdevice_t *subdevice;
- unsigned int chip_idx;
- int i;
-
- PDEBUG("executed.\n");
-
- // Allocate structure for device instance.
- me1600_device = kmalloc(sizeof(me1600_device_t), GFP_KERNEL);
-
- if (!me1600_device) {
- PERROR("Cannot get memory for device instance.\n");
- return NULL;
- }
-
- memset(me1600_device, 0, sizeof(me1600_device_t));
-
- // Initialize base class structure.
- err = me_device_pci_init((me_device_t *) me1600_device, pci_device);
-
- if (err) {
- kfree(me1600_device);
- PERROR("Cannot initialize device base class.\n");
- return NULL;
- }
- // Initialize spin lock .
- spin_lock_init(&me1600_device->config_regs_lock);
- spin_lock_init(&me1600_device->ao_shadows_lock);
-
- // Get the number of analog output subdevices.
- chip_idx =
- me1600_versions_get_device_index(me1600_device->base.info.pci.
- device_id);
-
- // Create shadow instance.
- me1600_device->ao_regs_shadows.count =
- me1600_versions[chip_idx].ao_chips;
- me1600_device->ao_regs_shadows.registry =
- kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(unsigned long),
- GFP_KERNEL);
- me1600_set_registry(me1600_device,
- me1600_device->base.info.pci.reg_bases[2]);
- me1600_device->ao_regs_shadows.shadow =
- kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(uint16_t),
- GFP_KERNEL);
- me1600_device->ao_regs_shadows.mirror =
- kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(uint16_t),
- GFP_KERNEL);
-
- // Create subdevice instances.
- for (i = 0; i < me1600_versions[chip_idx].ao_chips; i++) {
- subdevice =
- (me_subdevice_t *) me1600_ao_constructor(me1600_device->
- base.info.pci.
- reg_bases[2], i,
- ((me1600_versions
- [chip_idx].curr >
- i) ? 1 : 0),
- &me1600_device->
- config_regs_lock,
- &me1600_device->
- ao_shadows_lock,
- &me1600_device->
- ao_regs_shadows,
- me1600_workqueue);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me1600_device);
- kfree(me1600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me1600_device->base.slist,
- subdevice);
- }
-
- // Overwrite base class methods.
- me1600_device->base.me_device_destructor = me1600_destructor;
-
- return (me_device_t *) me1600_device;
-}
-EXPORT_SYMBOL(me1600_pci_constructor);
-
-static void me1600_destructor(struct me_device *device)
-{
- me1600_device_t *me1600_device = (me1600_device_t *) device;
- PDEBUG("executed.\n");
-
- // Destroy shadow instance.
- kfree(me1600_device->ao_regs_shadows.registry);
- kfree(me1600_device->ao_regs_shadows.shadow);
- kfree(me1600_device->ao_regs_shadows.mirror);
-
- me_device_deinit((me_device_t *) me1600_device);
- kfree(me1600_device);
-}
-
-static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base)
-{ // Create shadow structure.
- if (subdevice->ao_regs_shadows.count >= 1) {
- subdevice->ao_regs_shadows.registry[0] =
- (unsigned long)(reg_base + ME1600_CHANNEL_0_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 2) {
- subdevice->ao_regs_shadows.registry[1] =
- (unsigned long)(reg_base + ME1600_CHANNEL_1_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 3) {
- subdevice->ao_regs_shadows.registry[2] =
- (unsigned long)(reg_base + ME1600_CHANNEL_2_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 4) {
- subdevice->ao_regs_shadows.registry[3] =
- (unsigned long)(reg_base + ME1600_CHANNEL_3_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 5) {
- subdevice->ao_regs_shadows.registry[4] =
- (unsigned long)(reg_base + ME1600_CHANNEL_4_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 6) {
- subdevice->ao_regs_shadows.registry[5] =
- (unsigned long)(reg_base + ME1600_CHANNEL_5_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 7) {
- subdevice->ao_regs_shadows.registry[6] =
- (unsigned long)(reg_base + ME1600_CHANNEL_6_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 8) {
- subdevice->ao_regs_shadows.registry[7] =
- (unsigned long)(reg_base + ME1600_CHANNEL_7_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 9) {
- subdevice->ao_regs_shadows.registry[8] =
- (unsigned long)(reg_base + ME1600_CHANNEL_8_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 10) {
- subdevice->ao_regs_shadows.registry[9] =
- (unsigned long)(reg_base + ME1600_CHANNEL_9_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 11) {
- subdevice->ao_regs_shadows.registry[10] =
- (unsigned long)(reg_base + ME1600_CHANNEL_10_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 12) {
- subdevice->ao_regs_shadows.registry[11] =
- (unsigned long)(reg_base + ME1600_CHANNEL_11_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 13) {
- subdevice->ao_regs_shadows.registry[12] =
- (unsigned long)(reg_base + ME1600_CHANNEL_12_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 14) {
- subdevice->ao_regs_shadows.registry[13] =
- (unsigned long)(reg_base + ME1600_CHANNEL_13_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 15) {
- subdevice->ao_regs_shadows.registry[14] =
- (unsigned long)(reg_base + ME1600_CHANNEL_14_REG);
- }
- if (subdevice->ao_regs_shadows.count >= 16) {
- subdevice->ao_regs_shadows.registry[15] =
- (unsigned long)(reg_base + ME1600_CHANNEL_15_REG);
- }
- if (subdevice->ao_regs_shadows.count > 16) {
- PERROR("More than 16 outputs! (%d)\n",
- subdevice->ao_regs_shadows.count);
- }
-}
-
-// Init and exit of module.
-
-static int __init me1600_init(void)
-{
- PDEBUG("executed\n.");
-
- me1600_workqueue = create_singlethread_workqueue("me1600");
- return 0;
-}
-
-static void __exit me1600_exit(void)
-{
- PDEBUG("executed\n.");
-
- flush_workqueue(me1600_workqueue);
- destroy_workqueue(me1600_workqueue);
-}
-
-module_init(me1600_init);
-module_exit(me1600_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
- ("Guenter Gebhardt <g.gebhardt at meilhaus.de> & Krzysztof Gantzke <k.gantzke at meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for ME-1600 Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-1600 Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me1600_device.h b/drivers/staging/meilhaus/me1600_device.h
deleted file mode 100644
index c73aca1..0000000
--- a/drivers/staging/meilhaus/me1600_device.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * @file me1600_device.h
- *
- * @brief ME-1600 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME1600_H
-#define _ME1600_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-#include "me1600_ao.h"
-#include "me1600_ao_reg.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure to store device capabilities.
- */
-typedef struct me1600_version {
- uint16_t device_id; /**< The PCI device id of the device. */
- unsigned int ao_chips; /**< The number of analog outputs on the device. */
- int curr; /**< Flag to identify amounts of current output. */
-} me1600_version_t;
-
-/**
- * @brief Defines for each ME-1600 device version its capabilities.
- */
-static me1600_version_t me1600_versions[] = {
- {PCI_DEVICE_ID_MEILHAUS_ME1600_4U, 4, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME1600_8U, 8, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME1600_12U, 12, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME1600_16U, 16, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I, 16, 8},
- {0}
-};
-
-/**< Returns the number of entries in #me1600_versions. */
-#define ME1600_DEVICE_VERSIONS (ARRAY_SIZE(me1600_versions) - 1)
-
-/**
- * @brief Returns the index of the device entry in #me1600_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me1600_versions.
- */
-static inline unsigned int me1600_versions_get_device_index(uint16_t device_id)
-{
- unsigned int i;
- for (i = 0; i < ME1600_DEVICE_VERSIONS; i++)
- if (me1600_versions[i].device_id == device_id)
- break;
- return i;
-}
-
-/**
- * @brief The ME-1600 device class structure.
- */
-typedef struct me1600_device {
- me_device_t base; /**< The Meilhaus device base class. */
- spinlock_t config_regs_lock; /**< Protects the configuration registers. */
-
- me1600_ao_shadow_t ao_regs_shadows; /**< Addresses and shadows of output's registers. */
- spinlock_t ao_shadows_lock; /**< Protects the shadow's struct. */
-} me1600_device_t;
-
-/**
- * @brief The ME-1600 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-1600 device instance. \n
- * NULL on error.
- */
-me_device_t *me1600_pci_constructor(struct pci_dev *pci_device)
- __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_ai.c b/drivers/staging/meilhaus/me4600_ai.c
deleted file mode 100644
index fd9daa9..0000000
--- a/drivers/staging/meilhaus/me4600_ai.c
+++ /dev/null
@@ -1,3405 +0,0 @@
-/**
- * @file me4600_ai.c
- *
- * @brief ME-4000 analog input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "medebug.h"
-#include "meids.h"
-
-#include "me4600_reg.h"
-#include "me4600_ai_reg.h"
-#include "me4600_ai.h"
-
-/*
- * Declarations (local)
- */
-
-static void me4600_ai_destructor(struct me_subdevice *subdevice);
-static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice,
- struct file *filep, int flags);
-
-static int me4600_ai_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags);
-
-static int me4600_ai_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags);
-
-static int me4600_ai_io_stream_config(me_subdevice_t *subdevice,
- struct file *filep,
- meIOStreamConfig_t *config_list,
- int count,
- meIOStreamTrigger_t *trigger,
- int fifo_irq_threshold, int flags);
-static int me4600_ai_io_stream_read(me_subdevice_t *subdevice,
- struct file *filep,
- int read_mode,
- int *values, int *count, int flags);
-static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice,
- struct file *filep,
- int time_out, int *count, int flags);
-static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
- instance, int *values,
- const int count,
- const int flags);
-
-static int me4600_ai_io_stream_start(me_subdevice_t *subdevice,
- struct file *filep,
- int start_mode, int time_out, int flags);
-static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice,
- struct file *filep,
- int stop_mode, int flags);
-static int me4600_ai_io_stream_status(me_subdevice_t *subdevice,
- struct file *filep,
- int wait,
- int *status, int *values, int flags);
-
-static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice,
- int unit,
- int *min,
- int *max, int *maxdata, int *range);
-static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice,
- int unit, int *count);
-static int me4600_ai_query_range_info(me_subdevice_t *subdevice,
- int range,
- int *unit,
- int *min, int *max, int *maxdata);
-static int me4600_ai_query_timer(me_subdevice_t *subdevice,
- int timer,
- int *base_frequency,
- long long *min_ticks, long long *max_ticks);
-static int me4600_ai_query_number_channels(me_subdevice_t *subdevice,
- int *number);
-static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype);
-static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps);
-static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
- int cap, int *args, int count);
-
-static irqreturn_t me4600_ai_isr(int irq, void *dev_id);
-
-static int ai_mux_toggler(me4600_ai_subdevice_t *subdevice);
-
-/** Immidiate stop.
-* Reset all IRQ's sources. (block laches)
-* Preserve FIFO
-*/
-static int ai_stop_immediately(me4600_ai_subdevice_t *instance);
-
-/** Immidiate stop.
-* Reset all IRQ's sources. (block laches)
-* Reset data FIFO
-*/
-inline void ai_stop_isr(me4600_ai_subdevice_t *instance);
-
-/** Interrupt logics.
-* Read datas
-* Reset latches
-*/
-void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status,
- const uint32_t ctrl_status);
-void ai_infinite_isr(me4600_ai_subdevice_t *instance,
- const uint32_t irq_status, const uint32_t ctrl_status);
-
-/** Last chunck of datas. We must reschedule sample counter.
-* Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts.
-* When threshold is wrongly set some IRQ are lost.(!!!)
-*/
-inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance);
-
-/** Read datas from FIFO and copy them to buffer */
-static inline int ai_read_data(me4600_ai_subdevice_t *instance,
- const int count);
-
-/** Copy rest of data from fifo to circular buffer.*/
-static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance);
-
-/** Set ISM to next state for infinite data aqusation mode*/
-inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance);
-
-/** Set ISM to next state for define amount of data aqusation mode*/
-inline void ai_limited_ISM(me4600_ai_subdevice_t *instance,
- uint32_t irq_status);
-
-/** Set ISM to next stage for limited mode */
-inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance);
-
-static void me4600_ai_work_control_task(struct work_struct *work);
-
-/* Definitions
- */
-
-me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base,
- unsigned int channels,
- unsigned int ranges,
- int isolated,
- int sh,
- int irq,
- spinlock_t *ctrl_reg_lock,
- struct workqueue_struct *me4600_wq)
-{
- me4600_ai_subdevice_t *subdevice;
- int err;
- unsigned int i;
-
- PDEBUG("executed. idx=0\n");
-
- // Allocate memory for subdevice instance.
- subdevice = kmalloc(sizeof(me4600_ai_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me4600_ai_subdevice_t));
-
- // Initialize subdevice base class.
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- // Initialize circular buffer.
- subdevice->circ_buf.mask = ME4600_AI_CIRC_BUF_COUNT - 1;
-
- subdevice->circ_buf.buf =
- (void *)__get_free_pages(GFP_KERNEL, ME4600_AI_CIRC_BUF_SIZE_ORDER);
- PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf,
- ME4600_AI_CIRC_BUF_SIZE);
-
- if (!subdevice->circ_buf.buf) {
- PERROR("Cannot get circular buffer.\n");
- me_subdevice_deinit((me_subdevice_t *) subdevice);
- kfree(subdevice);
- return NULL;
- }
-
- memset(subdevice->circ_buf.buf, 0, ME4600_AI_CIRC_BUF_SIZE);
- subdevice->circ_buf.head = 0;
- subdevice->circ_buf.tail = 0;
- subdevice->status = ai_status_none;
-
- // Initialize wait queue.
- init_waitqueue_head(&subdevice->wait_queue);
-
- // Save the number of channels.
- subdevice->channels = channels;
-
- /* Initialize the single config entries to reset values */
- for (i = 0; i < channels; i++) {
- subdevice->single_config[i].status = ME_SINGLE_CHANNEL_NOT_CONFIGURED; //not configured
- }
-
- // Save if isolated device.
- subdevice->isolated = isolated;
-
- // Save if sample and hold is available.
- subdevice->sh = sh;
-
- // Set stream config to not configured state.
- subdevice->fifo_irq_threshold = 0;
- subdevice->data_required = 0;
- subdevice->chan_list_len = 0;
-
- // Initialize registers addresses.
- subdevice->ctrl_reg = reg_base + ME4600_AI_CTRL_REG;
- subdevice->status_reg = reg_base + ME4600_AI_STATUS_REG;
- subdevice->channel_list_reg = reg_base + ME4600_AI_CHANNEL_LIST_REG;
- subdevice->data_reg = reg_base + ME4600_AI_DATA_REG;
- subdevice->chan_timer_reg = reg_base + ME4600_AI_CHAN_TIMER_REG;
- subdevice->chan_pre_timer_reg = reg_base + ME4600_AI_CHAN_PRE_TIMER_REG;
- subdevice->scan_timer_low_reg = reg_base + ME4600_AI_SCAN_TIMER_LOW_REG;
- subdevice->scan_timer_high_reg =
- reg_base + ME4600_AI_SCAN_TIMER_HIGH_REG;
- subdevice->scan_pre_timer_low_reg =
- reg_base + ME4600_AI_SCAN_PRE_TIMER_LOW_REG;
- subdevice->scan_pre_timer_high_reg =
- reg_base + ME4600_AI_SCAN_PRE_TIMER_HIGH_REG;
- subdevice->start_reg = reg_base + ME4600_AI_START_REG;
- subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
- subdevice->sample_counter_reg = reg_base + ME4600_AI_SAMPLE_COUNTER_REG;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- // Initialize ranges.
- subdevice->ranges_len = ranges;
- subdevice->ranges[0].min = -10E6;
- subdevice->ranges[0].max = 9999694;
-
- subdevice->ranges[1].min = 0;
- subdevice->ranges[1].max = 9999847;
-
- subdevice->ranges[2].min = -25E5;
- subdevice->ranges[2].max = 2499923;
-
- subdevice->ranges[3].min = 0;
- subdevice->ranges[3].max = 2499961;
-
- // We have to switch the mux in order to get it work correctly.
- ai_mux_toggler(subdevice);
-
- // Register interrupt service routine.
- subdevice->irq = irq;
- if (request_irq(subdevice->irq, me4600_ai_isr,
- IRQF_DISABLED | IRQF_SHARED,
- ME4600_NAME, subdevice)) {
- PERROR("Cannot register interrupt service routine.\n");
- me_subdevice_deinit((me_subdevice_t *) subdevice);
- free_pages((unsigned long)subdevice->circ_buf.buf,
- ME4600_AI_CIRC_BUF_SIZE_ORDER);
- subdevice->circ_buf.buf = NULL;
- kfree(subdevice);
- return NULL;
- }
- PINFO("Registered irq=%d.\n", subdevice->irq);
-
- // Override base class methods.
- subdevice->base.me_subdevice_destructor = me4600_ai_destructor;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me4600_ai_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me4600_ai_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me4600_ai_io_single_read;
- subdevice->base.me_subdevice_io_stream_config =
- me4600_ai_io_stream_config;
- subdevice->base.me_subdevice_io_stream_new_values =
- me4600_ai_io_stream_new_values;
- subdevice->base.me_subdevice_io_stream_read = me4600_ai_io_stream_read;
- subdevice->base.me_subdevice_io_stream_start =
- me4600_ai_io_stream_start;
- subdevice->base.me_subdevice_io_stream_status =
- me4600_ai_io_stream_status;
- subdevice->base.me_subdevice_io_stream_stop = me4600_ai_io_stream_stop;
- subdevice->base.me_subdevice_query_number_channels =
- me4600_ai_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me4600_ai_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me4600_ai_query_subdevice_caps;
- subdevice->base.me_subdevice_query_subdevice_caps_args =
- me4600_ai_query_subdevice_caps_args;
- subdevice->base.me_subdevice_query_range_by_min_max =
- me4600_ai_query_range_by_min_max;
- subdevice->base.me_subdevice_query_number_ranges =
- me4600_ai_query_number_ranges;
- subdevice->base.me_subdevice_query_range_info =
- me4600_ai_query_range_info;
- subdevice->base.me_subdevice_query_timer = me4600_ai_query_timer;
-
- // Prepare work queue.
- subdevice->me4600_workqueue = me4600_wq;
-
-/* workqueue API changed in kernel 2.6.20 */
- INIT_DELAYED_WORK(&subdevice->ai_control_task,
- me4600_ai_work_control_task);
-
- return subdevice;
-}
-
-static void me4600_ai_destructor(struct me_subdevice *subdevice)
-{
- me4600_ai_subdevice_t *instance;
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=0\n");
-
- instance->ai_control_task_flag = 0;
- // Reset subdevice to asure clean exit.
- me4600_ai_io_reset_subdevice(subdevice, NULL,
- ME_IO_RESET_SUBDEVICE_NO_FLAGS);
-
- // Remove any tasks from work queue. This is paranoic because it was done allready in reset().
- if (!cancel_delayed_work(&instance->ai_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue.
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(2);
- }
-
- free_irq(instance->irq, instance);
- free_pages((unsigned long)instance->circ_buf.buf,
- ME4600_AI_CIRC_BUF_SIZE_ORDER);
- me_subdevice_deinit(&instance->base);
- kfree(instance);
-}
-
-static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice,
- struct file *filep, int flags)
-{
- me4600_ai_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- volatile uint32_t ctrl;
- unsigned long status;
- const int timeout = HZ / 10; //100ms
- int i;
-
- PDEBUG("executed. idx=0\n");
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- instance->ai_control_task_flag = 0;
- instance->status = ai_status_none;
-
- for (i = 0; i <= timeout; i++) {
- spin_lock_irqsave(instance->ctrl_reg_lock, status);
- ctrl = inl(instance->ctrl_reg);
- //Stop DMA
- ctrl &= ~ME4600_AI_CTRL_RPCI_FIFO;
- // Stop all actions. No conditions!
- ctrl &= ~ME4600_AI_CTRL_BIT_STOP;
- ctrl |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
-
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(instance->ctrl_reg_lock, status);
-
- if (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM))
- break;
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
-
- if (i > timeout) {
- PERROR("FSM is still busy.\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
-
- spin_lock_irqsave(instance->ctrl_reg_lock, status);
- ctrl = inl(instance->ctrl_reg);
- // Clear all features. Dissable interrupts.
- ctrl &= ~(ME4600_AI_CTRL_BIT_STOP
- | ME4600_AI_CTRL_BIT_LE_IRQ
- | ME4600_AI_CTRL_BIT_HF_IRQ | ME4600_AI_CTRL_BIT_SC_IRQ);
- ctrl |= (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP
- | ME4600_AI_CTRL_BIT_LE_IRQ_RESET
- | ME4600_AI_CTRL_BIT_HF_IRQ_RESET
- | ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
-
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(instance->ctrl_reg_lock, status);
-
- outl(ME4600_AI_MIN_CHAN_TICKS - 1, instance->chan_timer_reg);
- PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%llx\n",
- instance->reg_base,
- instance->chan_timer_reg - instance->reg_base,
- ME4600_AI_MIN_CHAN_TICKS);
- outl(ME4600_AI_MIN_ACQ_TICKS - 1, instance->chan_pre_timer_reg);
- PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%llx\n",
- instance->reg_base,
- instance->chan_pre_timer_reg - instance->reg_base,
- ME4600_AI_MIN_ACQ_TICKS);
- outl(0, instance->scan_timer_low_reg);
- PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_timer_low_reg - instance->reg_base, 0);
- outl(0, instance->scan_timer_high_reg);
- PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_timer_high_reg - instance->reg_base, 0);
- outl(0, instance->scan_pre_timer_low_reg);
- PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_pre_timer_low_reg - instance->reg_base, 0);
- outl(0, instance->scan_pre_timer_high_reg);
- PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_pre_timer_high_reg - instance->reg_base, 0);
- outl(0xEFFFFFFF, instance->sample_counter_reg);
- PDEBUG_REG("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sample_counter_reg - instance->reg_base,
- 0xEFFFFFFF);
-
- instance->circ_buf.head = 0;
- instance->circ_buf.tail = 0;
-
- instance->fifo_irq_threshold = 0;
- instance->data_required = 0;
- instance->chan_list_len = 0;
-
- // Initialize the single config entries to reset values.
- for (i = 0; i < instance->channels; i++) {
- instance->single_config[i].status =
- ME_SINGLE_CHANNEL_NOT_CONFIGURED;
- }
- instance->status = ai_status_none;
-
- //Signal reset if user is on wait.
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ai_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me4600_ai_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long cpu_flags;
- int i;
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=0\n");
-
- if (flags & ~ME_IO_SINGLE_CONFIG_CONTINUE) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- switch (trig_type) {
- case ME_TRIG_TYPE_SW:
- if (trig_edge != ME_TRIG_EDGE_NONE) {
- PERROR
- ("Invalid trigger edge. Software trigger has not edge.\n");
- return ME_ERRNO_INVALID_TRIG_EDGE;
- }
- break;
-
- case ME_TRIG_TYPE_EXT_ANALOG:
- if (instance->channels <= 16) //Only versions with 32 channels have analog trigger (4670 and 4680)
- {
- PERROR("Invalid trigger type specified.\n");
- return ME_ERRNO_INVALID_TRIG_TYPE;
- }
-
- case ME_TRIG_TYPE_EXT_DIGITAL:
- if ((trig_edge != ME_TRIG_EDGE_ANY)
- && (trig_edge != ME_TRIG_EDGE_RISING)
- && (trig_edge != ME_TRIG_EDGE_FALLING)) {
- PERROR("Invalid trigger edge specified.\n");
- return ME_ERRNO_INVALID_TRIG_EDGE;
- }
- break;
-
- default:
- PERROR("Invalid trigger type specified.\n");
- return ME_ERRNO_INVALID_TRIG_TYPE;
- }
-
- if (trig_chan != ME_TRIG_CHAN_DEFAULT) {
- PERROR("Invalid trigger channel specified.\n");
- return ME_ERRNO_INVALID_TRIG_CHAN;
- }
-
- if ((single_config < 0) || (single_config >= instance->ranges_len)) {
- PERROR("Invalid single config specified.\n");
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
-
- if ((ref != ME_REF_AI_GROUND) && (ref != ME_REF_AI_DIFFERENTIAL)) {
- PERROR("Invalid analog reference specified.\n");
- return ME_ERRNO_INVALID_REF;
- }
-
- if ((single_config % 2) && (ref != ME_REF_AI_GROUND)) {
- PERROR("Invalid analog reference specified.\n");
- return ME_ERRNO_INVALID_REF;
- }
-
- if ((ref == ME_REF_AI_DIFFERENTIAL)
- && ((instance->channels == 16) || (channel >= 16))) {
- PERROR("Invalid analog reference specified.\n");
- return ME_ERRNO_INVALID_REF;
- }
-
- if (channel < 0) {
- PERROR("Invalid channel number specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (channel >= instance->channels) {
- PERROR("Invalid channel number specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- //Prepare data entry.
- // Common for all modes.
- instance->single_config[channel].entry =
- channel | ME4600_AI_LIST_LAST_ENTRY;
-
- if (ref == ME_REF_AI_DIFFERENTIAL) { // ME_REF_AI_DIFFERENTIAL
- instance->single_config[channel].entry |=
- ME4600_AI_LIST_INPUT_DIFFERENTIAL;
- }
-/*
- // ME4600_AI_LIST_INPUT_SINGLE_ENDED = 0x0000
- // 'entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED' <== Do nothing. Removed.
- else
- {// ME_REF_AI_GROUND
- instance->single_config[channel].entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED;
- }
-*/
- switch (single_config) {
- case 0: //-10V..10V
-/*
- // ME4600_AI_LIST_RANGE_BIPOLAR_10 = 0x0000
- // 'entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10' <== Do nothing. Removed.
- instance->single_config[channel].entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10;
-*/ break;
-
- case 1: //0V..10V
- instance->single_config[channel].entry |=
- ME4600_AI_LIST_RANGE_UNIPOLAR_10;
- break;
-
- case 2: //-2.5V..2.5V
- instance->single_config[channel].entry |=
- ME4600_AI_LIST_RANGE_BIPOLAR_2_5;
- break;
-
- case 3: //0V..2.5V
- instance->single_config[channel].entry |=
- ME4600_AI_LIST_RANGE_UNIPOLAR_2_5;
- break;
- }
-
- // Prepare control register.
- // Common for all modes.
- instance->single_config[channel].ctrl =
- ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
-
- switch (trig_type) {
- case ME_TRIG_TYPE_SW:
- // Nothing to set.
- break;
-
- case ME_TRIG_TYPE_EXT_ANALOG:
- instance->single_config[channel].ctrl |=
- ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG;
-
- case ME_TRIG_TYPE_EXT_DIGITAL:
- instance->single_config[channel].ctrl |=
- ME4600_AI_CTRL_BIT_EX_TRIG;
- break;
- }
-
- switch (trig_edge) {
- case ME_TRIG_EDGE_RISING:
- // Nothing to set.
- break;
-
- case ME_TRIG_EDGE_ANY:
- instance->single_config[channel].ctrl |=
- ME4600_AI_CTRL_BIT_EX_TRIG_BOTH;
-
- case ME_TRIG_EDGE_FALLING:
- instance->single_config[channel].ctrl |=
- ME4600_AI_CTRL_BIT_EX_TRIG_FALLING;
- break;
- }
-
- // Enable this channel
- instance->single_config[channel].status = ME_SINGLE_CHANNEL_CONFIGURED;
-
- // Copy this settings to other outputs.
- if (flags == ME_IO_SINGLE_CONFIG_CONTINUE) {
- for (i = channel + 1; i < instance->channels; i++) {
- instance->single_config[i].ctrl =
- instance->single_config[channel].ctrl;
- instance->single_config[i].entry =
- instance->single_config[channel].entry;
- instance->single_config[i].status =
- ME_SINGLE_CHANNEL_CONFIGURED;
- }
- }
-
- instance->status = ai_status_single_configured;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ai_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me4600_ai_subdevice_t *instance;
- volatile uint32_t tmp;
- volatile uint32_t val;
- unsigned long cpu_flags;
- int err = ME_ERRNO_SUCCESS;
-
- unsigned long j;
- unsigned long delay = 0;
-
- PDEBUG("executed. idx=0\n");
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (instance->status != ai_status_single_configured) {
- PERROR("Subdevice not configured to work in single mode!\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-
- if ((channel > instance->channels) || (channel < 0)) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (instance->single_config[channel].status !=
- ME_SINGLE_CHANNEL_CONFIGURED) {
- PERROR("Channel is not configured to work in single mode!\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-
- if (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) {
- PERROR("Subdevice is busy.\n");
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
-
- ME_SUBDEVICE_ENTER;
-
- // Cancel control task
- PDEBUG("Cancel control task.\n");
- instance->ai_control_task_flag = 0;
- cancel_delayed_work(&instance->ai_control_task);
-
- if (time_out) {
- delay = (time_out * HZ) / 1000;
-
- if (delay == 0)
- delay = 1;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
- // Mark that StreamConfig is removed.
- instance->chan_list_len = 0;
-
- spin_lock(instance->ctrl_reg_lock);
- /// @note Imprtant: Preserve EXT IRQ settings.
- tmp = inl(instance->ctrl_reg);
- // Clear FIFOs and dissable interrupts
- tmp &=
- ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
-
- tmp &=
- ~(ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_HF_IRQ |
- ME4600_AI_CTRL_BIT_LE_IRQ);
- tmp |=
- ME4600_AI_CTRL_BIT_SC_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
- ME4600_AI_CTRL_BIT_LE_IRQ_RESET;
-
- tmp |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
-
- outl(0, instance->scan_pre_timer_low_reg);
- PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_pre_timer_low_reg - instance->reg_base, 0);
- outl(0, instance->scan_pre_timer_high_reg);
- PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_pre_timer_high_reg - instance->reg_base, 0);
- outl(0, instance->scan_timer_low_reg);
- PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_timer_low_reg - instance->reg_base, 0);
- outl(0, instance->scan_timer_high_reg);
- PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_timer_high_reg - instance->reg_base, 0);
- outl(65, instance->chan_timer_reg);
- PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->chan_timer_reg - instance->reg_base, 65);
- outl(65, instance->chan_pre_timer_reg);
- PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->chan_pre_timer_reg - instance->reg_base, 65);
-
- //Reactive FIFOs. Enable work.
- tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
-
- outl(instance->single_config[channel].entry,
- instance->channel_list_reg);
- PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->channel_list_reg - instance->reg_base,
- instance->single_config[channel].entry);
-
- // Preserve EXT IRQ settings.
- tmp &= (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
- outl(instance->single_config[channel].ctrl | tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- instance->single_config[channel].ctrl | tmp);
-
- spin_unlock(instance->ctrl_reg_lock);
-
- if (!(instance->single_config[channel].ctrl & ME4600_AI_CTRL_BIT_EX_TRIG)) { // Software start
- inl(instance->start_reg);
- PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
- instance->start_reg - instance->reg_base);
-
- delay = 2;
- }
-
- j = jiffies;
-
- while (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_EF_DATA)) {
- if (delay && ((jiffies - j) >= delay)) {
- if (!(instance->single_config[channel].ctrl & ME4600_AI_CTRL_BIT_EX_TRIG)) { // Software start.
- PERROR("Value not available after wait.\n");
- err = ME_ERRNO_INTERNAL;
- } else { // External start.
- PERROR("Timeout reached.\n");
- err = ME_ERRNO_TIMEOUT;
- }
- break;
- }
- // Wait
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
-
- if (signal_pending(current)) {
- PERROR
- ("Wait on external trigger interrupted by signal.\n");
- err = ME_ERRNO_SIGNAL;
- break;
- }
-
- if (instance->status != ai_status_single_configured) {
- PERROR("Wait interrupted by reset.\n");
- err = ME_ERRNO_CANCELLED;
- break;
- }
- }
-
- // Read value.
- if (!err) {
- val = inl(instance->data_reg) ^ 0x8000;
- PDEBUG_REG("data_reg inl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->data_reg - instance->reg_base, val);
- *value = val & ME4600_AI_MAX_DATA;
- } else {
- *value = 0xFFFFFFFF;
- }
-
- // Restore settings.
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
- // Clear FIFOs and dissable interrupts.
- tmp &=
- ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
- tmp |= ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_HF_IRQ;
- tmp |=
- ME4600_AI_CTRL_BIT_SC_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
- ME4600_AI_CTRL_BIT_LE_IRQ_RESET | ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- spin_unlock(instance->ctrl_reg_lock);
-
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ai_io_stream_config(me_subdevice_t *subdevice,
- struct file *filep,
- meIOStreamConfig_t *config_list,
- int count,
- meIOStreamTrigger_t *trigger,
- int fifo_irq_threshold, int flags)
-{
- me4600_ai_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- int i; // internal multipurpose variable
- unsigned long long data_required;
-
- volatile uint32_t entry;
- volatile uint32_t ctrl = ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
- volatile uint32_t tmp; // use when current copy of register's value needed
- unsigned long cpu_flags;
-
- uint64_t acq_ticks;
- uint64_t scan_ticks;
- uint64_t conv_ticks;
- unsigned int acq_start_ticks_low = trigger->iAcqStartTicksLow;
- unsigned int acq_start_ticks_high = trigger->iAcqStartTicksHigh;
- unsigned int scan_start_ticks_low = trigger->iScanStartTicksLow;
- unsigned int scan_start_ticks_high = trigger->iScanStartTicksHigh;
- unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
- unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
-
- PDEBUG("executed. idx=0\n");
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER
- // Convert ticks to 64 bit long values
- acq_ticks =
- (uint64_t) acq_start_ticks_low +
- ((uint64_t) acq_start_ticks_high << 32);
- scan_ticks =
- (uint64_t) scan_start_ticks_low +
- ((uint64_t) scan_start_ticks_high << 32);
- conv_ticks =
- (uint64_t) conv_start_ticks_low +
- ((uint64_t) conv_start_ticks_high << 32);
-
- // Check settings - begin
- switch (trigger->iAcqStartTrigType) {
- case ME_TRIG_TYPE_SW:
- case ME_TRIG_TYPE_EXT_DIGITAL:
- case ME_TRIG_TYPE_EXT_ANALOG:
- break;
-
- default:
- PERROR("Invalid acquisition start trigger type specified.\n");
- err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
- goto ERROR;
- break;
- }
-
- if ((trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW)
- && (trigger->iAcqStartTrigEdge != ME_TRIG_EDGE_NONE)) {
- PERROR("Invalid acquisition start trigger edge specified.\n");
- err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
- goto ERROR;
- }
-
- if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_SW) {
- switch (trigger->iAcqStartTrigEdge) {
- case ME_TRIG_EDGE_RISING:
- case ME_TRIG_EDGE_FALLING:
- case ME_TRIG_EDGE_ANY:
- break;
-
- default:
- PERROR
- ("Invalid acquisition start trigger edge specified.\n");
- err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
- goto ERROR;
- break;
- }
- }
-
- if (trigger->iAcqStartTrigChan != ME_TRIG_CHAN_DEFAULT) {
- PERROR
- ("Invalid acquisition start trigger channel specified.\n");
- err = ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
- goto ERROR;
- }
-
- if ((acq_ticks < ME4600_AI_MIN_ACQ_TICKS)
- || (acq_ticks > ME4600_AI_MAX_ACQ_TICKS)) {
- PERROR
- ("Invalid acquisition start trigger argument specified.\n");
- err = ME_ERRNO_INVALID_ACQ_START_ARG;
- goto ERROR;
- }
-
- switch (trigger->iScanStartTrigType) {
-
- case ME_TRIG_TYPE_TIMER:
- if ((scan_ticks < ME4600_AI_MIN_SCAN_TICKS)
- || (scan_ticks > ME4600_AI_MAX_SCAN_TICKS)
- || (scan_ticks < count * conv_ticks)
- ) {
- PERROR("Invalid scan start argument specified.\n");
- err = ME_ERRNO_INVALID_SCAN_START_ARG;
- goto ERROR;
- }
- break;
-
- case ME_TRIG_TYPE_EXT_DIGITAL:
- if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_DIGITAL) {
- PERROR
- ("Invalid scan start trigger type specified (Acq is HW digital)\n");
- err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
- goto ERROR;
- }
- break;
-
- case ME_TRIG_TYPE_EXT_ANALOG:
- if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_ANALOG) {
- PERROR
- ("Invalid scan start trigger type specified (Acq is HW analog)\n");
- err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
- goto ERROR;
- }
- break;
-
- case ME_TRIG_TYPE_FOLLOW:
- break;
-
- default:
- PERROR("Invalid scan start trigger type specified.\n");
- err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
- goto ERROR;
- break;
- }
-
- switch (trigger->iConvStartTrigType) {
-
- case ME_TRIG_TYPE_TIMER:
- if ((conv_ticks < ME4600_AI_MIN_CHAN_TICKS)
- || (conv_ticks > ME4600_AI_MAX_CHAN_TICKS)) {
- PERROR
- ("Invalid conv start trigger argument specified.\n");
- err = ME_ERRNO_INVALID_CONV_START_ARG;
- goto ERROR;
- }
- break;
-
- case ME_TRIG_TYPE_EXT_DIGITAL:
- if ((trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW)
- || (trigger->iAcqStartTrigType !=
- ME_TRIG_TYPE_EXT_DIGITAL)) {
- PERROR("Invalid conv start trigger type specified.\n");
- err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
- goto ERROR;
- }
- break;
-
- case ME_TRIG_TYPE_EXT_ANALOG:
- if ((trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW)
- || (trigger->iAcqStartTrigType !=
- ME_TRIG_TYPE_EXT_ANALOG)) {
- PERROR("Invalid conv start trigger type specified.\n");
- err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
- goto ERROR;
- }
- break;
-
- default:
- PERROR("Invalid conv start trigger type specified.\n");
- err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
- goto ERROR;
-
- break;
- }
-/**
-* Aceptable settings:
-* iScanStopTrigType : iAcqStopTrigType
-*
-* ME_TRIG_TYPE_NONE : ME_TRIG_TYPE_NONE -> infinite count with manual stop
-* ME_TRIG_TYPE_NONE : ME_TRIG_TYPE_COUNT -> stop after getting iScanStopCount list of values (iScanStopCount * count)
-* ME_TRIG_TYPE_COUNT : ME_TRIG_TYPE_FOLLOW -> stop after getting iAcqStopCount values (it can stops in midle of the list)
-*/
- switch (trigger->iScanStopTrigType) {
-
- case ME_TRIG_TYPE_NONE:
- break;
-
- case ME_TRIG_TYPE_COUNT:
- if (trigger->iScanStopCount <= 0) {
- PERROR("Invalid scan stop argument specified.\n");
- err = ME_ERRNO_INVALID_SCAN_STOP_ARG;
- goto ERROR;
- }
- break;
-
- default:
- PERROR("Invalid scan stop trigger type specified.\n");
- err = ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
- goto ERROR;
- break;
- }
-
- switch (trigger->iAcqStopTrigType) {
-
- case ME_TRIG_TYPE_NONE:
- if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
- PERROR("Invalid acq stop trigger type specified.\n");
- err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- goto ERROR;
- }
- break;
-
- case ME_TRIG_TYPE_FOLLOW:
- if (trigger->iScanStopTrigType != ME_TRIG_TYPE_COUNT) {
- PERROR("Invalid acq stop trigger type specified.\n");
- err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- goto ERROR;
- }
- break;
-
- case ME_TRIG_TYPE_COUNT:
- if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
- PERROR("Invalid acq stop trigger type specified.\n");
- err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- goto ERROR;
- }
-
- if (trigger->iAcqStopCount <= 0) {
- PERROR
- ("Invalid acquisition or scan stop argument specified.\n");
- err = ME_ERRNO_INVALID_ACQ_STOP_ARG;
- goto ERROR;
- }
- break;
-
- default:
- PERROR("Invalid acq stop trigger type specified.\n");
- err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- goto ERROR;
- break;
- }
-
- if ((count <= 0) || (count > ME4600_AI_LIST_COUNT)) {
- PERROR("Invalid channel list count specified.\n");
- err = ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
- goto ERROR;
- }
-///This is general limitation
-// if (fifo_irq_threshold < 0 || fifo_irq_threshold >= ME4600_AI_CIRC_BUF_COUNT)
-///This is limitation from Windows. I use it for compatibility.
- if (fifo_irq_threshold < 0
- || fifo_irq_threshold >= ME4600_AI_FIFO_COUNT) {
- PERROR("Invalid fifo irq threshold specified.\n");
- err = ME_ERRNO_INVALID_FIFO_IRQ_THRESHOLD;
- goto ERROR;
- }
-
- if ((config_list[0].iRef == ME_REF_AI_DIFFERENTIAL)
- && (instance->channels == 16)) {
- PERROR
- ("Differential reference is not available on this subdevice.\n");
- err = ME_ERRNO_INVALID_REF;
- goto ERROR;
- }
-
- if (flags & ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD) {
- if (!instance->sh) {
- PERROR
- ("Sample and hold is not available for this board.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- goto ERROR;
- }
- if (config_list[0].iRef == ME_REF_AI_DIFFERENTIAL) {
- PERROR
- ("Sample and hold is not available in differential mode.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- goto ERROR;
- }
- }
-
- for (i = 0; i < count; i++) {
- if ((config_list[i].iStreamConfig < 0)
- || (config_list[i].iStreamConfig >= instance->ranges_len)) {
- PERROR("Invalid stream config specified.\n");
- err = ME_ERRNO_INVALID_STREAM_CONFIG;
- goto ERROR;
- }
-
- if ((config_list[i].iRef != ME_REF_AI_GROUND)
- && (config_list[i].iRef != ME_REF_AI_DIFFERENTIAL)) {
- PERROR("Invalid references in the list. Ref=0x%x\n",
- config_list[i].iRef);
- err = ME_ERRNO_INVALID_REF;
- goto ERROR;
- }
-
- if (config_list[i].iStreamConfig % 2) { // StreamConfig: 1 or 3
- if (config_list[i].iRef == ME_REF_AI_DIFFERENTIAL) {
- PERROR
- ("Only bipolar modes support differential measurement.\n");
- err = ME_ERRNO_INVALID_REF;
- goto ERROR;
- }
- }
-
- if (config_list[i].iRef != config_list[0].iRef) {
- PERROR
- ("Not all references in the configuration list are equal. Ref[0]=0x%x Ref[%d]=0x%x\n",
- config_list[0].iRef, i, config_list[i].iRef);
- err = ME_ERRNO_INVALID_REF;
- goto ERROR;
- }
-
- if ((config_list[i].iRef == ME_REF_AI_DIFFERENTIAL)
- && (config_list[i].iChannel >= 16)) {
- PERROR("Channel not available in differential mode.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- goto ERROR;
- }
-
- if ((config_list[i].iChannel < 0)
- || (config_list[i].iChannel >= instance->channels)) {
- PERROR("Invalid channel number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- goto ERROR;
- }
- }
-
- // Check settings - end
-
- //Cancel control task
- PDEBUG("Cancel control task.\n");
- instance->ai_control_task_flag = 0;
- cancel_delayed_work(&instance->ai_control_task);
-
- // Work around from Keith Hartley - begin
- if (trigger->iScanStartTrigType == ME_TRIG_TYPE_TIMER) {
- if (count == 1) {
- // The hardware does not work properly with a non-zero scan time
- // if there is only ONE channel in the channel list. In this case
- // we must set the scan time to zero and use the channel time.
-
- conv_ticks = scan_ticks;
- trigger->iScanStartTrigType = ME_TRIG_TYPE_FOLLOW;
- } else if (scan_ticks == count * conv_ticks) {
- // Another hardware problem. If the number of scan ticks is
- // exactly equal to the number of channel ticks multiplied by
- // the number of channels then the sampling rate is reduced
- // by half.
- trigger->iScanStartTrigType = ME_TRIG_TYPE_FOLLOW;
- }
- }
- // Work around from Keith Hartley - end
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
- if (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) {
- PERROR("Subdevice is busy.\n");
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
-
- instance->status = ai_status_none;
- spin_lock(instance->ctrl_reg_lock);
- // Stop all actions. Block all interrupts. Clear (disable) FIFOs.
- ctrl =
- ME4600_AI_CTRL_BIT_LE_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
- ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
-
- tmp = inl(instance->ctrl_reg);
- // Preserve EXT IRQ and OFFSET settings. Clean other bits.
- tmp &=
- (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET |
- ME4600_AI_CTRL_BIT_FULLSCALE | ME4600_AI_CTRL_BIT_OFFSET);
-
- // Send it to register.
- outl(tmp | ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp | ctrl);
-
- // Enable channel fifo -> data fifo in stream_start().
- ctrl |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO;
- outl(tmp | ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp | ctrl);
- spin_unlock(instance->ctrl_reg_lock);
-
- // Write the channel list
- for (i = 0; i < count; i++) {
- entry = config_list[i].iChannel;
-
- switch (config_list[i].iStreamConfig) {
- case 0: //BIPOLAR 10V
-/*
- // ME4600_AI_LIST_RANGE_BIPOLAR_10 = 0x0000
- // 'entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10' <== Do nothing. Removed.
- entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10;
-*/
- break;
- case 1: //UNIPOLAR 10V
- entry |= ME4600_AI_LIST_RANGE_UNIPOLAR_10;
- break;
- case 2: //BIPOLAR 2.5V
- entry |= ME4600_AI_LIST_RANGE_BIPOLAR_2_5;
- break;
- case 3: //UNIPOLAR 2.5V
- entry |= ME4600_AI_LIST_RANGE_UNIPOLAR_2_5;
- break;
- default:
- PERROR_CRITICAL("UNCHECK ERROR in config_list!\n");
- PERROR_CRITICAL
- ("WRONG range\nPosition:%d Range:0x%04X\n", i,
- config_list[i].iStreamConfig);
- goto VERIFY_ERROR;
- break;
- }
-
- switch (config_list[i].iRef) {
- case ME_REF_AI_GROUND: //SINGLE ENDED
-/*
- // ME4600_AI_LIST_INPUT_SINGLE_ENDED = 0x0000
- // 'entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED' ==> Do nothing. Removed.
- entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED;
-*/ break;
- case ME_REF_AI_DIFFERENTIAL: //DIFFERENTIAL
- entry |= ME4600_AI_LIST_INPUT_DIFFERENTIAL;
- break;
- default:
- PERROR_CRITICAL("UNCHECK ERROR in config_list!\n");
- PERROR_CRITICAL
- ("WRONG reference\nPosition:%d Reference:0x%04X\n",
- i, config_list[i].iRef);
- goto VERIFY_ERROR;
- break;
- }
-
- //Add last entry flag
- if (i == (count - 1)) {
- entry |= ME4600_AI_LIST_LAST_ENTRY;
- }
-
- outl(entry, instance->channel_list_reg);
- PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->channel_list_reg - instance->reg_base,
- entry);
- }
-
- // Set triggering registers
- --acq_ticks;
- outl(acq_ticks, instance->chan_pre_timer_reg);
- PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%llX\n",
- instance->reg_base,
- instance->chan_pre_timer_reg - instance->reg_base,
- acq_ticks);
- outl(acq_ticks, instance->scan_pre_timer_low_reg);
- PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%llX\n",
- instance->reg_base,
- instance->scan_pre_timer_low_reg - instance->reg_base,
- acq_ticks & 0xFFFFFFFF);
- outl((acq_ticks >> 32), instance->scan_pre_timer_high_reg);
- PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%llX\n",
- instance->reg_base,
- instance->scan_pre_timer_high_reg - instance->reg_base,
- (acq_ticks >> 32) & 0xFFFFFFFF);
-
- // Set triggers
- switch (trigger->iAcqStartTrigType) {
- // Internal
- case ME_TRIG_TYPE_SW:
- // Nothing to set.
- break;
-
- // External
- case ME_TRIG_TYPE_EXT_ANALOG:
- ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG;
- case ME_TRIG_TYPE_EXT_DIGITAL:
- ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG;
-
- // External trigger needs edge's definition
- switch (trigger->iAcqStartTrigEdge) {
- case ME_TRIG_EDGE_RISING:
- // Nothing to set.
- break;
-
- case ME_TRIG_EDGE_FALLING:
- ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG_FALLING;
- break;
-
- case ME_TRIG_EDGE_ANY:
- ctrl |=
- ME4600_AI_CTRL_BIT_EX_TRIG_FALLING |
- ME4600_AI_CTRL_BIT_EX_TRIG_BOTH;
- break;
-
- default:
- PERROR_CRITICAL
- ("UNCHECK TRIGGER EDGE in triggers structure!\n");
- PERROR_CRITICAL
- ("WRONG acquisition start trigger:0x%04X.\n",
- trigger->iAcqStartTrigEdge);
- err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
- goto VERIFY_ERROR;
- break;
- }
- break;
-
- default:
- PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n");
- PERROR_CRITICAL("WRONG acquisition start trigger:0x%04X.\n",
- trigger->iAcqStartTrigType);
- err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
- goto VERIFY_ERROR;
- break;
- }
-
- switch (trigger->iScanStartTrigType) {
- case ME_TRIG_TYPE_TIMER:
- --scan_ticks;
- outl(scan_ticks, instance->scan_timer_low_reg);
- PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%llX\n",
- instance->reg_base,
- instance->scan_timer_low_reg - instance->reg_base,
- scan_ticks & 0xFFFFFFFF);
- outl((scan_ticks >> 32), instance->scan_timer_high_reg);
- PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%llX\n",
- instance->reg_base,
- instance->scan_timer_high_reg - instance->reg_base,
- (scan_ticks >> 32) & 0xFFFFFFFF);
-
- if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) {
- ctrl |= ME4600_AI_CTRL_BIT_MODE_0;
- } else {
- ctrl |= ME4600_AI_CTRL_BIT_MODE_1;
- }
- break;
-
- case ME_TRIG_TYPE_EXT_DIGITAL:
- case ME_TRIG_TYPE_EXT_ANALOG:
- outl(0, instance->scan_timer_low_reg);
- PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_timer_low_reg - instance->reg_base,
- 0);
- outl(0, instance->scan_timer_high_reg);
- PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_timer_high_reg - instance->reg_base,
- 0);
- ctrl |= ME4600_AI_CTRL_BIT_MODE_2;
- break;
-
- case ME_TRIG_TYPE_FOLLOW:
- outl(0, instance->scan_timer_low_reg);
- PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_timer_low_reg - instance->reg_base,
- 0);
- outl(0, instance->scan_timer_high_reg);
- PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_timer_high_reg - instance->reg_base,
- 0);
-
- if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) {
- ctrl |= ME4600_AI_CTRL_BIT_MODE_0;
- } else {
- ctrl |= ME4600_AI_CTRL_BIT_MODE_1;
- }
- break;
-
- default:
- PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n");
- PERROR_CRITICAL("WRONG scan start trigger:0x%04X.\n",
- trigger->iScanStartTrigType);
- err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
- goto VERIFY_ERROR;
- break;
- }
-
- switch (trigger->iConvStartTrigType) {
-
- case ME_TRIG_TYPE_TIMER:
- --conv_ticks;
- outl(conv_ticks, instance->chan_timer_reg);
- PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%llX\n",
- instance->reg_base,
- instance->chan_timer_reg - instance->reg_base,
- conv_ticks);
- break;
-
- case ME_TRIG_TYPE_EXT_DIGITAL:
- case ME_TRIG_TYPE_EXT_ANALOG:
- outl(0, instance->chan_timer_reg);
- PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->chan_timer_reg - instance->reg_base, 0);
- ctrl |= ME4600_AI_CTRL_BIT_MODE_0 | ME4600_AI_CTRL_BIT_MODE_1;
- break;
-
- default:
- PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n");
- PERROR_CRITICAL("WRONG conv start trigger:0x%04X.\n",
- trigger->iConvStartTrigType);
- err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
- goto VERIFY_ERROR;
-
- break;
- }
-
- //Sample & Hold feature
- if (flags & ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD) {
- if (instance->sh) {
- ctrl |= ME4600_AI_CTRL_BIT_SAMPLE_HOLD;
- } else {
- PERROR_CRITICAL("UNCHECK S&H feature!\n");
- err = ME_ERRNO_INVALID_FLAGS;
- goto VERIFY_ERROR;
- }
- }
- //Enable IRQs sources but leave latches blocked.
- 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!
-
- //Everything is good. Finalize
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
-
- //Preserve EXT IRQ and OFFSET settings. Clean other bits.
- tmp &=
- (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET |
- ME4600_AI_CTRL_BIT_FULLSCALE | ME4600_AI_CTRL_BIT_OFFSET);
-
- // write the control word
- outl(ctrl | tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl | tmp);
- spin_unlock(instance->ctrl_reg_lock);
-
- //Set the global parameters end exit.
- instance->chan_list_len = count;
- instance->fifo_irq_threshold = fifo_irq_threshold;
-
- if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) {
- data_required =
- (unsigned long long)trigger->iAcqStopCount *
- (unsigned long long)count;
- if (data_required > UINT_MAX)
- data_required = UINT_MAX;
- instance->data_required = (unsigned int)data_required;
- } else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT)
- instance->data_required =
- (unsigned long long)trigger->iScanStopCount;
- else
- instance->data_required = 0;
-
- // Mark subdevice as configured to work in stream mode.
- instance->status = ai_status_stream_configured;
-
- // Deinit single config. Set all entries to NOT_CONFIGURED.
- for (i = 0; i < instance->channels; i++) {
- instance->single_config[i].status =
- ME_SINGLE_CHANNEL_NOT_CONFIGURED;
- }
-
-VERIFY_ERROR: // Error in code. Wrong setting check. This should never ever happend!
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-ERROR: // Error in settings.
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice,
- struct file *filep,
- int time_out, int *count, int flags)
-{
- me4600_ai_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long t;
- unsigned long j;
- int volatile head;
-
- PDEBUG("executed. idx=0\n");
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (time_out < 0) {
- PERROR("Invalid time_out specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- t = (time_out * HZ) / 1000;
-
- if (t == 0)
- t = 1;
- } else { // Max time.
- t = LONG_MAX;
- }
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- j = jiffies;
-
- while (1) {
- // Only runing device can generate break.
- head = instance->circ_buf.head;
- wait_event_interruptible_timeout(instance->wait_queue,
- ((head !=
- instance->circ_buf.head)
- ||
- ((instance->status <=
- ai_status_stream_run_wait)
- && (instance->status >=
- ai_status_stream_end_wait))),
- t);
-
- if (head != instance->circ_buf.head) { // New data in buffer.
- break;
- } else if (instance->status == ai_status_stream_end) { // End of work.
- break;
- } else if (instance->status == ai_status_stream_fifo_error) {
- err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
- break;
- } else if (instance->status == ai_status_stream_buffer_error) {
- err = ME_ERRNO_RING_BUFFER_OVERFLOW;
- break;
- } else if (instance->status == ai_status_stream_error) {
- err = ME_ERRNO_INTERNAL;
- break;
- } else if ((jiffies - j) >= t) {
- PERROR("Wait on values timed out.\n");
- err = ME_ERRNO_TIMEOUT;
- break;
- } else if (signal_pending(current)) {
- PERROR("Wait on values interrupted from signal.\n");
- err = ME_ERRNO_SIGNAL;
- break;
- }
- // Correct timeout.
- t -= jiffies - j;
- }
-
- *count = me_circ_buf_values(&instance->circ_buf);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
- instance, int *values,
- const int count,
- const int flags)
-{
- int n;
- int i;
- uint32_t value;
-
- ///Checking how many datas can be copied.
- n = me_circ_buf_values(&instance->circ_buf);
- if (n <= 0)
- return 0;
-
- if (n > count)
- n = count;
-
- if (flags & ME_IO_STREAM_READ_FRAMES) {
- if (n < instance->chan_list_len) //Not enough data!
- return 0;
- n -= n % instance->chan_list_len;
- }
-
- for (i = 0; i < n; i++) {
- value = *(instance->circ_buf.buf + instance->circ_buf.tail);
- if (put_user(value, values + i)) {
- PERROR("Cannot copy new values to user.\n");
- return -ME_ERRNO_INTERNAL;
- }
- instance->circ_buf.tail++;
- instance->circ_buf.tail &= instance->circ_buf.mask;
- }
- return n;
-}
-
-static int me4600_ai_io_stream_read(me_subdevice_t *subdevice,
- struct file *filep,
- int read_mode,
- int *values, int *count, int flags)
-{
- me4600_ai_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- int ret;
-
- int c = *count;
- int min = c;
-
- PDEBUG("executed. idx=0\n");
-
- if (flags & ~ME_IO_STREAM_READ_FRAMES) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (!values || !count) {
- PERROR("Request has invalid pointer.\n");
- return ME_ERRNO_INVALID_POINTER;
- }
-
- if (c < 0) {
- PERROR("Request has invalid value's counter.\n");
- return ME_ERRNO_INVALID_VALUE_COUNT;
- }
-
- if ((read_mode != ME_READ_MODE_BLOCKING)
- && (read_mode != ME_READ_MODE_NONBLOCKING)) {
- PERROR("Invalid read mode specified.\n");
- return ME_ERRNO_INVALID_READ_MODE;
- }
-
- if (c == 0) { //You get what you want! Nothing more or less.
- return ME_ERRNO_SUCCESS;
- }
-
- instance = (me4600_ai_subdevice_t *) subdevice;
- ME_SUBDEVICE_ENTER;
-
- //Check if subdevice is configured.
- if (instance->chan_list_len <= 0) {
- PERROR("Subdevice wasn't configured.\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-
- if (flags & ME_IO_STREAM_READ_FRAMES) {
- if (c < instance->chan_list_len) { //Not enough data requested.
- PERROR
- ("When using FRAME_READ mode minimal size is defined by channel list.\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INVALID_VALUE_COUNT;
- }
- }
-
- if (c > (ME4600_AI_CIRC_BUF_COUNT - instance->chan_list_len)) { // To return acceptable amount of data when user pass too big value.
- min = ME4600_AI_CIRC_BUF_COUNT - instance->chan_list_len;
- }
-
- if (flags & ME_IO_STREAM_READ_FRAMES) {
- //Wait for whole list.
- if (read_mode == ME_READ_MODE_BLOCKING) {
- min = c - (c % instance->chan_list_len);
- }
-
- if (read_mode == ME_READ_MODE_NONBLOCKING) {
- min = instance->chan_list_len;
- }
- }
-
- if ((inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM)) { //Working
- //If blocking mode -> wait for data.
- if ((me_circ_buf_values(&instance->circ_buf) < min)
- && (read_mode == ME_READ_MODE_BLOCKING)) {
- wait_event_interruptible(instance->wait_queue,
- ((me_circ_buf_values
- (&instance->circ_buf) >= min)
- || !(inl(instance->status_reg)
- &
- ME4600_AI_STATUS_BIT_FSM)));
-
- if (signal_pending(current)) {
- PERROR
- ("Wait on values interrupted from signal.\n");
- err = ME_ERRNO_SIGNAL;
- }
- }
- }
-
- ret = me4600_ai_io_stream_read_get_value(instance, values, c, flags);
- if (ret < 0) {
- err = -ret;
- *count = 0;
- } else if (ret == 0) {
- *count = 0;
- if (instance->status == ai_status_stream_fifo_error) {
- err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
- instance->status = ai_status_stream_end;
- } else if (instance->status == ai_status_stream_buffer_error) {
- err = ME_ERRNO_RING_BUFFER_OVERFLOW;
- instance->status = ai_status_stream_end;
- } else if (instance->status == ai_status_stream_end) {
- err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
- } else if (instance->status == ai_status_stream_error) {
- err = ME_ERRNO_INTERNAL;
- } else if (instance->status == ai_status_none) {
- PDEBUG("Stream canceled.\n");
- err = ME_ERRNO_INTERNAL;
- }
- } else {
- *count = ret;
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-/** @brief Stop aqusation. Preserve FIFOs.
-*
-* @param instance The subdevice instance (pointer).
-*/
-
-static int ai_stop_immediately(me4600_ai_subdevice_t *instance)
-{
- unsigned long cpu_flags = 0;
- volatile uint32_t ctrl;
- const int timeout = HZ / 10; //100ms
- int i;
-
- for (i = 0; i <= timeout; i++) {
- spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl &= ~ME4600_AI_CTRL_BIT_STOP;
- ctrl |=
- (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP |
- ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
- ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-
- if (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM)) { // Exit.
- break;
- }
-
- PINFO("Wait for stop: %d\n", i + 1);
- //Still working!
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
-
- if (i > timeout) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- return ME_ERRNO_INTERNAL;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_io_stream_start(me_subdevice_t *subdevice,
- struct file *filep,
- int start_mode, int time_out, int flags)
-{
- me4600_ai_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long cpu_flags = 0;
- unsigned long ref;
- unsigned long delay = 0;
-
- volatile uint32_t tmp;
-
- PDEBUG("executed. idx=0\n");
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((start_mode != ME_START_MODE_BLOCKING)
- && (start_mode != ME_START_MODE_NONBLOCKING)) {
- PERROR("Invalid start mode specified.\n");
- return ME_ERRNO_INVALID_START_MODE;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- delay = (time_out * HZ) / 1000;
-
- if (delay == 0)
- delay = 1;
- }
-
- ME_SUBDEVICE_ENTER
- spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
-
- tmp = inl(instance->ctrl_reg);
-
- if ((tmp & ME4600_AI_STATUS_BIT_FSM)) {
- PERROR("Conversion is already running.\n");
- spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- if (instance->chan_list_len == 0) { //Not configured!
- PERROR("Subdevice is not configured to work in stream mode!\n");
- spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
- err = ME_ERRNO_PREVIOUS_CONFIG;
- goto ERROR;
- }
-
- 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
- PERROR("Subdevice is configured to work in single mode.\n");
- spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
- err = ME_ERRNO_PREVIOUS_CONFIG;
- goto ERROR;
- }
- //Reset stop bits.
- tmp |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_STOP;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
-
- //Start datas' FIFO.
- tmp |= ME4600_AI_CTRL_BIT_DATA_FIFO;
- //Free stop bits.
- tmp &= ~(ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_STOP);
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-
- //Cancel control task
- PDEBUG("Cancel control task.\n");
- instance->ai_control_task_flag = 0;
- cancel_delayed_work(&instance->ai_control_task);
-
- //Set the starting values.
- instance->ISM.global_read = 0;
- instance->ISM.read = 0;
- //Clear circular buffer
- instance->circ_buf.head = 0;
- instance->circ_buf.tail = 0;
-
- //Set everything.
- ai_data_acquisition_logic(instance);
-
- //Set status to 'wait for start'
- instance->status = ai_status_stream_run_wait;
-
- // Set control task's timeout
- instance->timeout.delay = delay;
- instance->timeout.start_time = jiffies;
-
- //Lets go! Start work
- inl(instance->start_reg);
- PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
- instance->start_reg - instance->reg_base);
-
- // Schedule control task
- instance->ai_control_task_flag = 1;
- queue_delayed_work(instance->me4600_workqueue,
- &instance->ai_control_task, 1);
-
- PDEVELOP("Delay:%ld\n", delay);
-
- if (start_mode == ME_START_MODE_BLOCKING) { //Wait for start.
- ref = jiffies;
- //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
- wait_event_interruptible_timeout(instance->wait_queue,
- (instance->status !=
- ai_status_stream_run_wait),
- (delay) ? delay +
- 1 : LONG_MAX);
-
- if ((instance->status != ai_status_stream_run)
- && (instance->status != ai_status_stream_end)) {
- PDEBUG("Starting stream canceled. %d\n",
- instance->status);
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on start of state machine interrupted.\n");
- instance->status = ai_status_none;
- ai_stop_isr(instance);
- err = ME_ERRNO_SIGNAL;
- } else if ((delay) && ((jiffies - ref) > delay)) {
- if (instance->status != ai_status_stream_run) {
- if (instance->status == ai_status_stream_end) {
- PDEBUG("Timeout reached.\n");
- } else if ((jiffies - ref) > delay + 1) {
- PERROR
- ("Timeout reached. Not handled by control task!\n");
- ai_stop_isr(instance);
- instance->status =
- ai_status_stream_error;
- } else {
- PERROR
- ("Timeout reached. Signal come but status is strange: %d\n",
- instance->status);
- ai_stop_isr(instance);
- instance->status =
- ai_status_stream_error;
- }
-
- instance->ai_control_task_flag = 0;
- cancel_delayed_work(&instance->ai_control_task);
- err = ME_ERRNO_TIMEOUT;
- }
- }
- }
-#ifdef MEDEBUG_INFO
- tmp = inl(instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
-
- PINFO("STATUS_BIT_FSM=%s.\n",
- (tmp & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off");
- PINFO("CTRL_BIT_HF_IRQ=%s.\n",
- (tmp & ME4600_AI_CTRL_BIT_HF_IRQ) ? "enable" : "disable");
- PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n",
- (tmp & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" : "work");
- PINFO("CTRL_BIT_SC_IRQ=%s.\n",
- (tmp & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable");
- PINFO("CTRL_BIT_SC_RELOAD=%s.\n",
- (tmp & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off");
- PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n",
- (tmp & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" : "work");
-#endif
-
-ERROR:
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ai_io_stream_status(me_subdevice_t *subdevice,
- struct file *filep,
- int wait,
- int *status, int *values, int flags)
-{
- me4600_ai_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed. idx=0\n");
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- switch (instance->status) {
- case ai_status_single_configured:
- case ai_status_stream_configured:
- case ai_status_stream_end:
- case ai_status_stream_fifo_error:
- case ai_status_stream_buffer_error:
- case ai_status_stream_error:
- *status = ME_STATUS_IDLE;
- break;
-
- case ai_status_stream_run_wait:
- case ai_status_stream_run:
- case ai_status_stream_end_wait:
- *status = ME_STATUS_BUSY;
- break;
-
- case ai_status_none:
- default:
- *status =
- (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) ?
- ME_STATUS_BUSY : ME_STATUS_IDLE;
- break;
- }
-
- if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) {
- // Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
- wait_event_interruptible_timeout(instance->wait_queue,
- ((instance->status !=
- ai_status_stream_run_wait)
- && (instance->status !=
- ai_status_stream_run)
- && (instance->status !=
- ai_status_stream_end_wait)),
- LONG_MAX);
-
- if (instance->status != ai_status_stream_end) {
- PDEBUG("Wait for IDLE canceled. %d\n",
- instance->status);
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait for IDLE interrupted.\n");
- instance->status = ai_status_none;
- ai_stop_isr(instance);
- err = ME_ERRNO_SIGNAL;
- }
-
- *status = ME_STATUS_IDLE;
- }
-
- *values = me_circ_buf_values(&instance->circ_buf);
- PDEBUG("me_circ_buf_values(&instance->circ_buf)=%d.\n", *values);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice,
- struct file *filep,
- int stop_mode, int flags)
-{
-/**
- @note Stop is implemented only in blocking mode.
- @note Function return when state machine is stoped.
-*/
- me4600_ai_subdevice_t *instance;
- unsigned long cpu_flags;
- uint32_t ctrl;
- int ret;
-
- PDEBUG("executed. idx=0\n");
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((stop_mode != ME_STOP_MODE_IMMEDIATE)
- && (stop_mode != ME_STOP_MODE_LAST_VALUE)) {
- PERROR("Invalid stop mode specified.\n");
- return ME_ERRNO_INVALID_STOP_MODE;
- }
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- // Mark as stopping. => Software stop.
- instance->status = ai_status_stream_end_wait;
-
- if (stop_mode == ME_STOP_MODE_IMMEDIATE) {
- ret = ai_stop_immediately(instance);
-
- if (ret) {
- PERROR("FSM is still busy.\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
- instance->ai_control_task_flag = 0;
-
- } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
- // Set stop bit in registry.
- spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl |= ME4600_AI_CTRL_BIT_STOP;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-
- // Only runing process will interrupt this call. Events are signaled when status change.
- wait_event_interruptible_timeout(instance->wait_queue,
- (instance->status !=
- ai_status_stream_end_wait),
- LONG_MAX);
-
- if (instance->status != ai_status_stream_end) {
- PDEBUG("Stopping stream canceled.\n");
- ret = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Stopping stream interrupted.\n");
- instance->status = ai_status_none;
- ret = ME_ERRNO_SIGNAL;
- }
- // End of work.
- ai_stop_immediately(instance);
-
- }
-
- ret = ai_read_data_pooling(instance);
- if (ret > 0) { // Everything fine. More datas put to software buffer.
- instance->status = ai_status_stream_end;
- ret = ME_ERRNO_SUCCESS;
- // Signal that we put last data to software buffer.
- wake_up_interruptible_all(&instance->wait_queue);
- } else if (ret == 0) { // Everything fine. No more datas in FIFO.
- instance->status = ai_status_stream_end;
- ret = ME_ERRNO_SUCCESS;
- } else if (ret == -ME_ERRNO_RING_BUFFER_OVERFLOW) { // Stop is unsuccessful, buffer is overflow.
- instance->status = ai_status_stream_buffer_error;
- ret = ME_ERRNO_SUCCESS;
- } else { // Stop is unsuccessful
- instance->status = ai_status_stream_end;
- ret = -ret;
- }
-
- ME_SUBDEVICE_EXIT;
-
- return ret;
-}
-
-static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice,
- int unit,
- int *min,
- int *max, int *maxdata, int *range)
-{
- me4600_ai_subdevice_t *instance;
- int i;
- int r = -1;
- int diff = 21E6;
-
- PDEBUG("executed. idx=0\n");
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- if ((*max - *min) < 0) {
- PERROR("Invalid minimum and maximum values specified.\n");
- return ME_ERRNO_INVALID_MIN_MAX;
- }
-
- if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
- for (i = 0; i < instance->ranges_len; i++) {
- if ((instance->ranges[i].min <= *min)
- && ((instance->ranges[i].max + 1000) >= *max)) {
- if ((instance->ranges[i].max -
- instance->ranges[i].min) - (*max - *min) <
- diff) {
- r = i;
- diff =
- (instance->ranges[i].max -
- instance->ranges[i].min) - (*max -
- *min);
- }
- }
- }
-
- if (r < 0) {
- PERROR("No matching range found.\n");
- return ME_ERRNO_NO_RANGE;
- } else {
- *min = instance->ranges[r].min;
- *max = instance->ranges[r].max;
- *maxdata = ME4600_AI_MAX_DATA;
- *range = r;
- }
- } else {
- PERROR("Invalid physical unit specified.\n");
- return ME_ERRNO_INVALID_UNIT;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice,
- int unit, int *count)
-{
- me4600_ai_subdevice_t *instance;
-
- PDEBUG("executed. idx=0\n");
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
- *count = instance->ranges_len;
- } else {
- *count = 0;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_range_info(me_subdevice_t *subdevice,
- int range,
- int *unit,
- int *min, int *max, int *maxdata)
-{
- me4600_ai_subdevice_t *instance;
-
- PDEBUG("executed. idx=0\n");
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- if ((range < instance->ranges_len) && (range >= 0)) {
- *unit = ME_UNIT_VOLT;
- *min = instance->ranges[range].min;
- *max = instance->ranges[range].max;
- *maxdata = ME4600_AI_MAX_DATA;
- } else {
- PERROR("Invalid range number specified.\n");
- return ME_ERRNO_INVALID_RANGE;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_timer(me_subdevice_t *subdevice,
- int timer,
- int *base_frequency,
- long long *min_ticks, long long *max_ticks)
-{
- me4600_ai_subdevice_t *instance;
-
- PDEBUG("executed. idx=0\n");
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- switch (timer) {
-
- case ME_TIMER_ACQ_START:
- *base_frequency = ME4600_AI_BASE_FREQUENCY;
- *min_ticks = ME4600_AI_MIN_ACQ_TICKS;
- *max_ticks = ME4600_AI_MAX_ACQ_TICKS;
- break;
-
- case ME_TIMER_SCAN_START:
- *base_frequency = ME4600_AI_BASE_FREQUENCY;
- *min_ticks = ME4600_AI_MIN_SCAN_TICKS;
- *max_ticks = ME4600_AI_MAX_SCAN_TICKS;
- break;
-
- case ME_TIMER_CONV_START:
- *base_frequency = ME4600_AI_BASE_FREQUENCY;
- *min_ticks = ME4600_AI_MIN_CHAN_TICKS;
- *max_ticks = ME4600_AI_MAX_CHAN_TICKS;
- break;
-
- default:
- PERROR("Invalid timer specified.(0x%04x)\n", timer);
-
- return ME_ERRNO_INVALID_TIMER;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- me4600_ai_subdevice_t *instance;
-
- PDEBUG("executed. idx=0\n");
-
- instance = (me4600_ai_subdevice_t *) subdevice;
- *number = instance->channels;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed. idx=0\n");
-
- *type = ME_TYPE_AI;
- *subtype = ME_SUBTYPE_STREAMING;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- PDEBUG("executed. idx=0\n");
-
- *caps =
- ME_CAPS_AI_TRIG_SYNCHRONOUS | ME_CAPS_AI_FIFO |
- ME_CAPS_AI_FIFO_THRESHOLD;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
- int cap, int *args, int count)
-{
- me4600_ai_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- instance = (me4600_ai_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=0\n");
-
- if (count != 1) {
- PERROR("Invalid capability argument count.\n");
- return ME_ERRNO_INVALID_CAP_ARG_COUNT;
- }
-
- switch (cap) {
- case ME_CAP_AI_FIFO_SIZE:
- args[0] = ME4600_AI_FIFO_COUNT;
- break;
-
- case ME_CAP_AI_BUFFER_SIZE:
- args[0] =
- (instance->circ_buf.buf) ? ME4600_AI_CIRC_BUF_COUNT : 0;
- break;
-
- default:
- PERROR("Invalid capability.\n");
- err = ME_ERRNO_INVALID_CAP;
- args[0] = 0;
- }
-
- return err;
-}
-
-void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status,
- const uint32_t ctrl_status)
-{
- int to_read;
-
- if (!instance->fifo_irq_threshold) { //No threshold provided. SC ends work. HF need reseting.
- if (irq_status & ME4600_IRQ_STATUS_BIT_SC) {
- if (ai_read_data(instance, instance->ISM.next) != instance->ISM.next) { //ERROR!
- PERROR
- ("Limited amounts aqusition with TH=0: Circular buffer full!\n");
- instance->status =
- ai_status_stream_buffer_error;
- } else {
- instance->status = ai_status_stream_end;
- }
- //End of work.
- ai_stop_isr(instance);
- } else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) {
- instance->ISM.global_read += ME4600_AI_FIFO_HALF;
-
- if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) { //ERROR!
- PERROR
- ("Limited amounts aqusition with TH = 0: Circular buffer full!\n");
- //End of work.
- ai_stop_isr(instance);
- instance->status =
- ai_status_stream_buffer_error;
- } else {
- //Continue.
- ai_limited_ISM(instance, irq_status);
- }
- }
- //Signal user.
- wake_up_interruptible_all(&instance->wait_queue);
- } else //if(instance->fifo_irq_threshold)
- {
- if (irq_status & ME4600_IRQ_STATUS_BIT_SC) {
- instance->ISM.read = 0;
- if ((instance->fifo_irq_threshold < ME4600_AI_FIFO_HALF)
- && (!(ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA)))
- {
- to_read =
- ME4600_AI_FIFO_HALF -
- (ME4600_AI_FIFO_HALF %
- instance->fifo_irq_threshold);
- PDEBUG
- ("Limited amounts aqusition with TH != 0: Not fast enough data aqusition! correction=%d\n",
- to_read);
- } else {
- to_read = instance->ISM.next;
- }
- instance->ISM.global_read += to_read;
-
- ai_reschedule_SC(instance);
-
- if (ai_read_data(instance, to_read) != to_read) { //ERROR!
- PERROR
- ("Limited amounts aqusition with TH != 0: Circular buffer full!\n");
- //End of work.
- ai_stop_isr(instance);
- instance->status =
- ai_status_stream_buffer_error;
- } else {
- //Continue.
- ai_limited_ISM(instance, irq_status);
- }
-
- //Signal user.
- wake_up_interruptible_all(&instance->wait_queue);
- } else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) {
- instance->ISM.read += ME4600_AI_FIFO_HALF;
- instance->ISM.global_read += ME4600_AI_FIFO_HALF;
-
- if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) { //ERROR!
- PERROR
- ("Limited amounts aqusition with TH != 0: Circular buffer full!\n");
- ai_stop_isr(instance);
-
- instance->status =
- ai_status_stream_buffer_error;
- //Signal user.
- wake_up_interruptible_all(&instance->
- wait_queue);
- } else {
- //Countinue.
- ai_limited_ISM(instance, irq_status);
- }
- }
-
- if (instance->ISM.global_read >= instance->data_required) { //End of work. Next paranoid pice of code: '>=' instead od '==' only to be sure.
- ai_stop_isr(instance);
- if (instance->status < ai_status_stream_end) {
- instance->status = ai_status_stream_end;
- }
-#ifdef MEDEBUG_ERROR
- if (instance->ISM.global_read > instance->data_required) { //This is security check case. This should never ever happend!
- PERROR
- ("Limited amounts aqusition: Read more data than necessary! data_required=%d < read=%d\n",
- instance->data_required,
- instance->ISM.global_read);
- //Signal error (warning??).
- instance->status = ai_status_stream_error;
- }
-#endif
- }
- }
-}
-
-void ai_infinite_isr(me4600_ai_subdevice_t *instance,
- const uint32_t irq_status, const uint32_t ctrl_status)
-{
- int to_read;
-
- if (irq_status & ME4600_IRQ_STATUS_BIT_SC) { //next chunck of data -> read fifo
- //Set new state in ISM.
- 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.
- if (instance->fifo_irq_threshold) {
- to_read =
- ME4600_AI_FIFO_HALF -
- (ME4600_AI_FIFO_HALF %
- instance->fifo_irq_threshold);
- if (to_read > instance->fifo_irq_threshold) {
- PDEBUG
- ("Infinite aqusition: Not fast enough data aqusition! TH != 0: correction=%d\n",
- to_read);
- }
- } else { //No threshold specified.
- to_read = ME4600_AI_FIFO_HALF;
- }
- } else {
- to_read = instance->ISM.next;
- }
-
- instance->ISM.read += to_read;
-
- //Get data
- if (ai_read_data(instance, to_read) != to_read) { //ERROR!
- PERROR("Infinite aqusition: Circular buffer full!\n");
- ai_stop_isr(instance);
- instance->status = ai_status_stream_buffer_error;
- } else {
- ai_infinite_ISM(instance);
- instance->ISM.global_read += instance->ISM.read;
- instance->ISM.read = 0;
- }
-
- //Signal data to user
- wake_up_interruptible_all(&instance->wait_queue);
- } else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) { //fifo is half full -> read fifo Large blocks only!
- instance->ISM.read += ME4600_AI_FIFO_HALF;
-
- if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) { //ERROR!
- PERROR("Infinite aqusition: Circular buffer full!\n");
- ai_stop_isr(instance);
- instance->status = ai_status_stream_buffer_error;
-
- //Signal it.
- wake_up_interruptible_all(&instance->wait_queue);
- } else {
- ai_infinite_ISM(instance);
- }
- }
-}
-
-static irqreturn_t me4600_ai_isr(int irq, void *dev_id)
-{ /// @note This is time critical function!
- uint32_t irq_status;
- uint32_t ctrl_status;
- me4600_ai_subdevice_t *instance = dev_id;
- //int to_read;
-
- PDEBUG("executed. idx=0\n");
-
- if (irq != instance->irq) {
- PERROR("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- irq_status = inl(instance->irq_status_reg);
- if (!
- (irq_status &
- (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC))) {
-#ifdef MEDEBUG_INFO
- 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.
- PINFO
- ("%ld Shared interrupt. %s(): irq_status_reg=LE_IRQ\n",
- jiffies, __func__);
- } else {
- PINFO
- ("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n",
- jiffies, __func__, irq_status);
- }
-#endif
- return IRQ_NONE;
- }
-
- if (!instance->circ_buf.buf) { //Security check.
- PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n");
- ai_stop_isr(instance);
- return IRQ_HANDLED;
- }
- //Get the status register.
- ctrl_status = inl(instance->status_reg);
-
-#ifdef MEDEBUG_INFO
- if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF)
- PINFO("HF interrupt active\n");
- if (irq_status & ME4600_IRQ_STATUS_BIT_SC)
- PINFO("SC interrupt active\n");
- if (irq_status & ME4600_IRQ_STATUS_BIT_LE)
- PINFO("LE interrupt active\n");
-#endif
-
- //This is safety check!
- if ((irq_status & ME4600_IRQ_STATUS_BIT_AI_HF)
- && (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA)) {
- PDEBUG("HF interrupt active but FIFO under half\n");
- //Reset HF interrupt latch.
- spin_lock(instance->ctrl_reg_lock);
- outl(ctrl_status | ME4600_AI_CTRL_BIT_HF_IRQ_RESET,
- instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl_status);
- outl(ctrl_status, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl_status);
- spin_unlock(instance->ctrl_reg_lock);
- return IRQ_HANDLED;
- }
-#ifdef MEDEBUG_INFO
- PINFO("STATUS_BIT_FSM=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off");
-
- PINFO("STATUS_BIT_EF_CHANNEL=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_EF_CHANNEL) ? "not empty" :
- "empty");
- PINFO("STATUS_BIT_HF_CHANNEL=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_HF_CHANNEL) ? " < HF" :
- " > HF");
- PINFO("STATUS_BIT_FF_CHANNEL=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_FF_CHANNEL) ? "not full" :
- "full");
-
- PINFO("STATUS_BIT_EF_DATA=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_EF_DATA) ? "not empty" :
- "empty");
- PINFO("STATUS_BIT_HF_DATA=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA) ? " < HF" : " > HF");
- PINFO("STATUS_BIT_FF_DATA=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA) ? "not full" :
- "full");
-
- PINFO("CTRL_BIT_HF_IRQ=%s.\n",
- (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ) ? "enable" : "disable");
- PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n",
- (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" :
- "work");
- PINFO("CTRL_BIT_SC_IRQ=%s.\n",
- (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable");
- PINFO("CTRL_BIT_SC_RELOAD=%s.\n",
- (ctrl_status & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off");
- PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n",
- (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" :
- "work");
-#endif
-
- //Look for overflow error.
- if (!(ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA)) {
- //FIFO is full. Read datas and reset all settings.
- PERROR("FIFO overflow.\n");
- ai_read_data(instance, ME4600_AI_FIFO_COUNT);
- ai_stop_isr(instance);
-
- instance->status = ai_status_stream_fifo_error;
- //Signal it.
- wake_up_interruptible_all(&instance->wait_queue);
-
- return IRQ_HANDLED;
- }
-
- if (!instance->data_required) { //This is infinite aqusition.
-#ifdef MEDEBUG_ERROR
- if ((irq_status &
- (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC))
- ==
- (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC)) {
- ///In infinite mode only one interrupt source should be reported!
- PERROR
- ("Error in ISM! Infinite aqusition: HF and SC interrupts active! threshold=%d next=%d ctrl=0x%04X irq_status_reg=0x%04X",
- instance->fifo_irq_threshold, instance->ISM.next,
- ctrl_status, irq_status);
- }
-#endif
-
- ai_infinite_isr(instance, irq_status, ctrl_status);
-
-#ifdef MEDEBUG_INFO
- ctrl_status = inl(instance->ctrl_reg);
-#endif
- } else {
-
- ai_limited_isr(instance, irq_status, ctrl_status);
- ctrl_status = inl(instance->status_reg);
- 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
- PDEBUG
- ("MISSED HF. data_required=%d ISM.read=%d ISM.global=%d ISM.next=%d\n",
- instance->data_required, instance->ISM.read,
- instance->ISM.global_read, instance->ISM.next);
- ai_limited_isr(instance, ME4600_IRQ_STATUS_BIT_AI_HF,
- ctrl_status);
- }
- }
-
-#ifdef MEDEBUG_INFO
- PINFO("STATUS_BIT_FSM=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off");
-
- PINFO("STATUS_BIT_EF_CHANNEL=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_EF_CHANNEL) ? "not empty" :
- "empty");
- PINFO("STATUS_BIT_HF_CHANNEL=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_HF_CHANNEL) ? " < HF" :
- " > HF");
- PINFO("STATUS_BIT_FF_CHANNEL=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_FF_CHANNEL) ? "not full" :
- "full");
-
- PINFO("STATUS_BIT_EF_DATA=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_EF_DATA) ? "not empty" :
- "empty");
- PINFO("STATUS_BIT_HF_DATA=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA) ? " < HF" : " > HF");
- PINFO("STATUS_BIT_FF_DATA=%s.\n",
- (ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA) ? "not full" :
- "full");
-
- PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n",
- (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" :
- "work");
- PINFO("CTRL_BIT_SC_IRQ=%s.\n",
- (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable");
- PINFO("CTRL_BIT_SC_RELOAD=%s.\n",
- (ctrl_status & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off");
- PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n",
- (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" :
- "work");
- PINFO("%ld END\n", jiffies);
-#endif
-
- return IRQ_HANDLED;
-}
-
-/** @brief Stop aqusation of data. Reset interrupts' laches. Clear data's FIFO.
-*
-* @param instance The subdevice instance (pointer).
-*/
-inline void ai_stop_isr(me4600_ai_subdevice_t *instance)
-{ /// @note This is soft time critical function!
- register uint32_t tmp;
-
- spin_lock(instance->ctrl_reg_lock);
- //Stop all. Reset interrupt laches. Reset data FIFO.
- tmp = inl(instance->ctrl_reg);
- tmp |=
- (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_HF_IRQ_RESET
- | ME4600_AI_CTRL_BIT_LE_IRQ_RESET |
- ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
- tmp &= ~ME4600_AI_CTRL_BIT_DATA_FIFO;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- spin_unlock(instance->ctrl_reg_lock);
-}
-
-/** @brief Copy data from fifo to circular buffer.
-*
-* @param instance The subdevice instance (pointer).
-* @param count The number of requested data.
-*
-* @return On success: Number of copied values.
-* @return On error: -ME_ERRNO_RING_BUFFER_OVERFLOW.
-*/
-static inline int ai_read_data(me4600_ai_subdevice_t *instance,
- const int count)
-{ /// @note This is time critical function!
- int c = count;
- int empty_space;
- int copied = 0;
- int i, j;
-
- empty_space = me_circ_buf_space_to_end(&instance->circ_buf);
- if (empty_space <= 0) {
- PDEBUG("Circular buffer full.\n");
- return -ME_ERRNO_RING_BUFFER_OVERFLOW;
- }
-
- if (empty_space < c) { //Copy first part. Max to end of buffer.
- PDEBUG
- ("Try to copy %d values from FIFO to circular buffer (pass 1).\n",
- empty_space);
- for (i = 0; i < empty_space; i++) {
- *(instance->circ_buf.buf + instance->circ_buf.head) =
- (inw(instance->data_reg) ^ 0x8000);
- instance->circ_buf.head++;
- }
- instance->circ_buf.head &= instance->circ_buf.mask;
- c -= empty_space;
- copied = empty_space;
-
- empty_space = me_circ_buf_space_to_end(&instance->circ_buf);
- }
-
- if (empty_space > 0) {
- j = (empty_space < c) ? empty_space : c;
- PDEBUG
- ("Try to copy %d values from FIFO to circular buffer (pass 2).\n",
- c);
- for (i = 0; i < j; i++) {
- *(instance->circ_buf.buf + instance->circ_buf.head) =
- (inw(instance->data_reg) ^ 0x8000);
- instance->circ_buf.head++;
- }
- instance->circ_buf.head &= instance->circ_buf.mask;
- copied += j;
- }
- return copied;
-}
-
-inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance)
-{ /// @note This is time critical function!
- register volatile uint32_t ctrl_set, ctrl_reset, tmp;
-
- if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) { // Only sample counter with reloadnig is working. Reset it.
- PINFO
- ("Only sample counter with reloadnig is working. Reset it.\n");
- ctrl_set = ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
- ctrl_reset = ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
- } 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.
- PINFO
- ("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");
- ctrl_set =
- ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
- ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
- ctrl_reset =
- ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
- ME4600_AI_CTRL_BIT_HF_IRQ_RESET);
- } 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.
- PINFO
- ("This is HF interrupt for large block.The next interrupt should be from HF, also. Reset HF.\n");
- ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
- ctrl_reset = ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
- } else { //This is HF interrupt for large block.The next interrupt should be from SC. Don't reset HF!
- PINFO
- ("This is HF interrupt for large block.The next interrupt should be from SC. Don't reset HF!\n");
- ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
- ctrl_reset = 0xFFFFFFFF;
- }
-
- //Reset interrupt latch.
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
- PINFO("ctrl=0x%x ctrl_set=0x%x ctrl_reset=0x%x\n", tmp, ctrl_set,
- ctrl_reset);
- tmp |= ctrl_set;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- if (ctrl_reset != 0xFFFFFFFF) {
- outl(tmp & ctrl_reset, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reset outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- tmp & ctrl_reset);
- }
- spin_unlock(instance->ctrl_reg_lock);
-
-}
-
-inline void ai_limited_ISM(me4600_ai_subdevice_t *instance,
- uint32_t irq_status)
-{ /// @note This is time critical function!
- register volatile uint32_t ctrl_set, ctrl_reset = 0xFFFFFFFF, tmp;
-
- if (!instance->fifo_irq_threshold) { //No threshold provided. SC ends work.
- PINFO("No threshold provided. SC ends work.\n");
- ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
- if (instance->data_required > (ME4600_AI_FIFO_COUNT - 1 + instance->ISM.global_read)) { //HF need reseting.
- ctrl_reset &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
- }
- } else //if(instance->fifo_irq_threshold)
- {
- if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) {
- PINFO("Threshold provided. Clear HF latch.\n");
- ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-
- if (instance->fifo_irq_threshold >= (ME4600_AI_FIFO_MAX_SC + instance->ISM.read)) { //This is not the last one. HF need reseting.
- PINFO
- ("The next interrupt is HF. HF need be activating.\n");
- ctrl_reset = ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
- }
- }
-
- if (irq_status & ME4600_IRQ_STATUS_BIT_SC) {
- PINFO("Threshold provided. Restart SC.\n");
- ctrl_set = ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
- ctrl_reset &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
-
- if (instance->fifo_irq_threshold >= ME4600_AI_FIFO_MAX_SC) { //This is not the last one. HF need to be activating.
- PINFO
- ("The next interrupt is HF. HF need to be activating.\n");
- ctrl_reset &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
- }
- }
- }
-
- //Reset interrupt latch.
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
- tmp |= ctrl_set;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
-
- if (ctrl_reset != 0xFFFFFFFF) {
- outl(tmp & ctrl_reset, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- tmp & ctrl_reset);
- }
- spin_unlock(instance->ctrl_reg_lock);
-
-}
-
-/** @brief Last chunck of datas. We must reschedule sample counter.
-* @note Last chunck.
-* Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts.
-* @warning When threshold is wrongly set some IRQ are lost.(!!!)
-*/
-inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance)
-{
- register uint32_t rest;
-
- if (instance->data_required <= instance->ISM.global_read)
- return;
-
- rest = instance->data_required - instance->ISM.global_read;
- if (rest < instance->fifo_irq_threshold) { //End of work soon ....
- PDEBUG("Rescheduling SC from %d to %d.\n",
- instance->fifo_irq_threshold, rest);
- /// @note Write new value to SC <== DANGER! This is not safe solution! We can miss some inputs.
- outl(rest, instance->sample_counter_reg);
- PDEBUG_REG("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sample_counter_reg - instance->reg_base,
- rest);
- instance->fifo_irq_threshold = rest;
-
- if (rest < ME4600_AI_FIFO_MAX_SC) {
- instance->ISM.next = rest;
- } else {
- instance->ISM.next = rest % ME4600_AI_FIFO_HALF;
- if (instance->ISM.next + ME4600_AI_FIFO_HALF <
- ME4600_AI_FIFO_MAX_SC) {
- instance->ISM.next += ME4600_AI_FIFO_HALF;
- }
- }
- }
-}
-
-/** Start the ISM. All must be reseted before enter to this function. */
-inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance)
-{
- register uint32_t tmp;
-
- if (!instance->data_required) { //This is infinite aqusition.
- if (!instance->fifo_irq_threshold) { //No threshold provided. Set SC to 0.5*FIFO. Clear the SC's latch.
- //Set the sample counter
- outl(ME4600_AI_FIFO_HALF, instance->sample_counter_reg);
- PDEBUG_REG
- ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sample_counter_reg - instance->reg_base,
- ME4600_AI_FIFO_HALF);
- } else { //Threshold provided. Set SC to treshold. Clear the SC's latch.
- //Set the sample counter
- outl(instance->fifo_irq_threshold,
- instance->sample_counter_reg);
- PDEBUG_REG
- ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sample_counter_reg - instance->reg_base,
- instance->fifo_irq_threshold);
- }
-
- if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) { //Enable only sample counter's interrupt. Set reload bit. Clear the SC's latch.
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
- tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD;
- tmp &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- tmp);
- spin_unlock(instance->ctrl_reg_lock);
- if (!instance->fifo_irq_threshold) { //No threshold provided. Set ISM.next to 0.5*FIFO.
- instance->ISM.next = ME4600_AI_FIFO_HALF;
- } else { //Threshold provided. Set ISM.next to treshold.
- instance->ISM.next =
- instance->fifo_irq_threshold;
- }
- } else { //Enable sample counter's and HF's interrupts.
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
- tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD;
- tmp &=
- ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
- ME4600_AI_CTRL_BIT_HF_IRQ_RESET);
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- tmp);
- spin_unlock(instance->ctrl_reg_lock);
-
- instance->ISM.next =
- instance->fifo_irq_threshold % ME4600_AI_FIFO_HALF;
- if (instance->ISM.next + ME4600_AI_FIFO_HALF <
- ME4600_AI_FIFO_MAX_SC) {
- instance->ISM.next += ME4600_AI_FIFO_HALF;
- }
- }
- } else { //This aqusition is limited to set number of data.
- if (instance->fifo_irq_threshold >= instance->data_required) { //Stupid situation.
- instance->fifo_irq_threshold = 0;
- PDEBUG
- ("Stupid situation: data_required(%d) < threshold(%d).\n",
- instance->fifo_irq_threshold,
- instance->data_required);
- }
-
- if (!instance->fifo_irq_threshold) { //No threshold provided. Easy case: HF=read and SC=end.
- //Set the sample counter to data_required.
- outl(instance->data_required,
- instance->sample_counter_reg);
- PDEBUG_REG
- ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sample_counter_reg - instance->reg_base,
- instance->data_required);
-
- //Reset the latches of sample counter and HF (if SC>FIFO).
- //No SC reload!
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
- tmp &=
- ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
- ME4600_AI_CTRL_BIT_SC_RELOAD);
- if (instance->data_required >
- (ME4600_AI_FIFO_COUNT - 1)) {
- tmp &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
- instance->ISM.next =
- instance->data_required %
- ME4600_AI_FIFO_HALF;
- instance->ISM.next += ME4600_AI_FIFO_HALF;
-
- } else {
- instance->ISM.next = instance->data_required;
- }
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- tmp);
- spin_unlock(instance->ctrl_reg_lock);
-
- } else { //The most general case. We have concret numbe of required data and threshold. SC=TH
- //Set the sample counter to threshold.
- outl(instance->fifo_irq_threshold,
- instance->sample_counter_reg);
- PDEBUG_REG
- ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->sample_counter_reg - instance->reg_base,
- instance->fifo_irq_threshold);
-
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
- //In this moment we are sure that SC will come more than once.
- tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD;
-
- if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) { //The threshold is so small that we do need HF.
- tmp &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
- instance->ISM.next =
- instance->fifo_irq_threshold;
- } else { //The threshold is large. The HF must be use.
- tmp &=
- ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
- ME4600_AI_CTRL_BIT_HF_IRQ_RESET);
- instance->ISM.next =
- instance->fifo_irq_threshold %
- ME4600_AI_FIFO_HALF;
- if (instance->ISM.next + ME4600_AI_FIFO_HALF <
- ME4600_AI_FIFO_MAX_SC) {
- instance->ISM.next +=
- ME4600_AI_FIFO_HALF;
- }
- }
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- tmp);
- spin_unlock(instance->ctrl_reg_lock);
- }
- }
-}
-
-static int ai_mux_toggler(me4600_ai_subdevice_t *instance)
-{
- uint32_t tmp;
-
- PDEBUG("executed. idx=0\n");
-
- outl(0, instance->scan_pre_timer_low_reg);
- PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_pre_timer_low_reg - instance->reg_base, 0);
- outl(0, instance->scan_pre_timer_high_reg);
- PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_pre_timer_high_reg - instance->reg_base, 0);
- outl(0, instance->scan_timer_low_reg);
- PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_timer_low_reg - instance->reg_base, 0);
- outl(0, instance->scan_timer_high_reg);
- PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->scan_timer_high_reg - instance->reg_base, 0);
- outl(65, instance->chan_timer_reg);
- PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->chan_timer_reg - instance->reg_base, 65);
- outl(65, instance->chan_pre_timer_reg);
- PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->chan_pre_timer_reg - instance->reg_base, 65);
-
- // Turn on internal reference.
- tmp = inl(instance->ctrl_reg);
- tmp |= ME4600_AI_CTRL_BIT_FULLSCALE;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
-
- // Clear data and channel fifo.
- tmp &=
- ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
-
- // Write channel entry.
- outl(ME4600_AI_LIST_INPUT_DIFFERENTIAL |
- ME4600_AI_LIST_RANGE_UNIPOLAR_2_5 | 31,
- instance->channel_list_reg);
- PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->channel_list_reg - instance->reg_base,
- ME4600_AI_LIST_INPUT_DIFFERENTIAL |
- ME4600_AI_LIST_RANGE_UNIPOLAR_2_5 | 31);
-
- // Start conversion.
- inl(instance->start_reg);
- PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
- instance->start_reg - instance->reg_base);
- udelay(10);
-
- // Clear data and channel fifo.
- tmp &=
- ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
-
- // Write channel entry.
- // ME4600_AI_LIST_INPUT_SINGLE_ENDED | ME4600_AI_LIST_RANGE_BIPOLAR_10 <= 0x0000
- outl(ME4600_AI_LIST_INPUT_SINGLE_ENDED |
- ME4600_AI_LIST_RANGE_BIPOLAR_10, instance->channel_list_reg);
- PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->channel_list_reg - instance->reg_base,
- ME4600_AI_LIST_INPUT_SINGLE_ENDED |
- ME4600_AI_LIST_RANGE_BIPOLAR_10);
-
- // Start conversion.
- inl(instance->start_reg);
- PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
- instance->start_reg - instance->reg_base);
- udelay(10);
-
- // Clear control register.
- tmp &= (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
-
- return ME_ERRNO_SUCCESS;
-}
-
-/** @brief Copy rest of data from fifo to circular buffer.
-* @note Helper for STOP command. After FSM is stopped.
-* @note This is slow function that copy all remainig data from FIFO to buffer.
-*
-* @param instance The subdevice instance (pointer).
-*
-* @return On success: Number of copied values.
-* @return On error: Negative error code -ME_ERRNO_RING_BUFFER_OVERFLOW.
-*/
-static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance)
-{ /// @note This is time critical function!
- int empty_space;
- int copied = 0;
- int status = ME_ERRNO_SUCCESS;
-
- PDEBUG("Space left in circular buffer = %d.\n",
- me_circ_buf_space(&instance->circ_buf));
-
- while ((empty_space = me_circ_buf_space(&instance->circ_buf))) {
- if (!(status = inl(instance->status_reg) & ME4600_AI_STATUS_BIT_EF_DATA)) { //No more data. status = ME_ERRNO_SUCCESS = 0
- break;
- }
- *(instance->circ_buf.buf + instance->circ_buf.head) =
- (inw(instance->data_reg) ^ 0x8000);
- instance->circ_buf.head++;
- instance->circ_buf.head &= instance->circ_buf.mask;
- }
-
-#ifdef MEDEBUG_ERROR
- if (!status)
- PDEBUG
- ("Copied all remaining datas (%d) from FIFO to circular buffer.\n",
- copied);
- else {
- PDEBUG("No more empty space in buffer.\n");
- PDEBUG("Copied %d datas from FIFO to circular buffer.\n",
- copied);
- PDEBUG("FIFO still not empty.\n");
- }
-#endif
- return (!status) ? copied : -ME_ERRNO_RING_BUFFER_OVERFLOW;
-}
-
-static void me4600_ai_work_control_task(struct work_struct *work)
-{
- me4600_ai_subdevice_t *instance;
- uint32_t status;
- uint32_t ctrl;
- unsigned long cpu_flags = 0;
- int reschedule = 0;
- int signaling = 0;
-
- instance =
- container_of((void *)work, me4600_ai_subdevice_t, ai_control_task);
- PINFO("<%s: %ld> executed.\n", __func__, jiffies);
-
- status = inl(instance->status_reg);
- PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->status_reg - instance->reg_base, status);
-
- switch (instance->status) { // Checking actual mode.
- // Not configured for work.
- case ai_status_none:
- break;
-
- //This are stable modes. No need to do anything. (?)
- case ai_status_single_configured:
- case ai_status_stream_configured:
- case ai_status_stream_fifo_error:
- case ai_status_stream_buffer_error:
- case ai_status_stream_error:
- PERROR("Shouldn't be running!.\n");
- break;
-
- // Stream modes
- case ai_status_stream_run_wait:
- if (status & ME4600_AI_STATUS_BIT_FSM) { // ISM started..
- instance->status = ai_status_stream_run;
- // Signal the end of wait for start.
- signaling = 1;
- // Wait now for stop.
- reschedule = 1;
- break;
-
- // Check timeout.
- if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
- PDEBUG("Timeout reached.\n");
- // Stop all actions. No conditions! Block interrupts. Reset FIFO => Too late!
- ai_stop_isr(instance);
-
- instance->status = ai_status_stream_end;
-
- // Signal the end.
- signaling = 1;
- }
- }
- break;
-
- case ai_status_stream_run:
- // Wait for stop ISM.
- reschedule = 1;
- break;
-
- case ai_status_stream_end_wait:
- if (!(status & ME4600_AI_STATUS_BIT_FSM)) { // ISM stoped. Overwrite ISR.
- instance->status = ai_status_stream_end;
- // Signal the end of wait for stop.
- signaling = 1;
- } else {
- // Wait for stop ISM.
- reschedule = 1;
- }
- break;
-
- case ai_status_stream_end:
- //End work.
- if (status & ME4600_AI_STATUS_BIT_FSM) { // Still working? Stop it!
- PERROR
- ("Status is 'ai_status_stream_end' but hardware is still working!\n");
- spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP |
- ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
- ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl);
- spin_unlock_irqrestore(instance->ctrl_reg_lock,
- cpu_flags);
- }
- break;
-
- default:
- PERROR_CRITICAL("Status is in wrong state (%d)!\n",
- instance->status);
- instance->status = ai_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
-
- }
-
- if (signaling) { //Signal it.
- wake_up_interruptible_all(&instance->wait_queue);
- }
-
- if (instance->ai_control_task_flag && reschedule) { // Reschedule task
- queue_delayed_work(instance->me4600_workqueue,
- &instance->ai_control_task, 1);
- } else {
- PINFO("<%s> Ending control task.\n", __func__);
- }
-
-}
diff --git a/drivers/staging/meilhaus/me4600_ai.h b/drivers/staging/meilhaus/me4600_ai.h
deleted file mode 100644
index 7055e44..0000000
--- a/drivers/staging/meilhaus/me4600_ai.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * @file me4600_ai.h
- *
- * @brief Meilhaus ME-4000 analog input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_AI_H_
-#define _ME4600_AI_H_
-
-#include "mesubdevice.h"
-#include "meioctl.h"
-#include "mecirc_buf.h"
-
-#ifdef __KERNEL__
-
-#define ME4600_AI_MAX_DATA 0xFFFF
-
-#ifdef ME_SYNAPSE
-# define ME4600_AI_CIRC_BUF_SIZE_ORDER 8 // 2^n PAGES =>> Maximum value of 1MB for Synapse
-#else
-# define ME4600_AI_CIRC_BUF_SIZE_ORDER 5 // 2^n PAGES =>> 128KB
-#endif
-#define ME4600_AI_CIRC_BUF_SIZE PAGE_SIZE<<ME4600_AI_CIRC_BUF_SIZE_ORDER // Buffer size in bytes.
-
-#ifdef _CBUFF_32b_t
-# define ME4600_AI_CIRC_BUF_COUNT ((ME4600_AI_CIRC_BUF_SIZE) / sizeof(uint32_t)) // Size in values
-#else
-# define ME4600_AI_CIRC_BUF_COUNT ((ME4600_AI_CIRC_BUF_SIZE) / sizeof(uint16_t)) // Size in values
-#endif
-
-#define ME4600_AI_FIFO_HALF 1024 //ME4600_AI_FIFO_COUNT/2 //1024
-#define ME4600_AI_FIFO_MAX_SC 1352 //0.66*ME4600_AI_FIFO_COUNT //1352
-
-typedef enum ME4600_AI_STATUS {
- ai_status_none = 0,
- ai_status_single_configured,
- ai_status_stream_configured,
- ai_status_stream_run_wait,
- ai_status_stream_run,
- ai_status_stream_end_wait,
- ai_status_stream_end,
- ai_status_stream_fifo_error,
- ai_status_stream_buffer_error,
- ai_status_stream_error,
- ai_status_last
-} ME4600_AI_STATUS;
-
-typedef struct me4600_single_config_entry {
- unsigned short status;
- uint32_t entry;
- uint32_t ctrl;
-} me4600_single_config_entry_t;
-
-typedef struct me4600_range_entry {
- int min;
- int max;
-} me4600_range_entry_t;
-
-typedef struct me4600_ai_ISM {
- volatile unsigned int global_read; /**< The number of data read in total. */
- volatile unsigned int read; /**< The number of data read for this chunck. */
- volatile unsigned int next; /**< The number of data request by user. */
-} me4600_ai_ISM_t;
-
-typedef struct me4600_ai_timeout {
- unsigned long start_time;
- unsigned long delay;
-} me4600_ai_timeout_t;
-
-/**
- * @brief The ME-4000 analog input subdevice class.
- */
-typedef struct me4600_ai_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
-
- /* Hardware feautres */
- unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */
- int isolated; /**< Marks if this subdevice is on an optoisolated device. */
- int sh; /**< Marks if this subdevice has sample and hold devices. */
-
- unsigned int channels; /**< The number of channels available on this subdevice. */
- me4600_single_config_entry_t single_config[32]; /**< The configuration set for single acquisition. */
-
- unsigned int data_required; /**< The number of data request by user. */
- unsigned int fifo_irq_threshold; /**< The user adjusted FIFO high water interrupt level. */
- unsigned int chan_list_len; /**< The length of the user defined channel list. */
-
- me4600_ai_ISM_t ISM; /**< The information request by Interrupt-State-Machine. */
- volatile enum ME4600_AI_STATUS status; /**< The current stream status flag. */
- me4600_ai_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
-
- /* Registers *//**< All registers are 32 bits long. */
- unsigned long ctrl_reg;
- unsigned long status_reg;
- unsigned long channel_list_reg;
- unsigned long data_reg;
- unsigned long chan_timer_reg;
- unsigned long chan_pre_timer_reg;
- unsigned long scan_timer_low_reg;
- unsigned long scan_timer_high_reg;
- unsigned long scan_pre_timer_low_reg;
- unsigned long scan_pre_timer_high_reg;
- unsigned long start_reg;
- unsigned long irq_status_reg;
- unsigned long sample_counter_reg;
-
- unsigned int ranges_len;
- me4600_range_entry_t ranges[4]; /**< The ranges available on this subdevice. */
-
- /* Software buffer */
- me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. */
- wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
-
- struct workqueue_struct *me4600_workqueue;
- struct delayed_work ai_control_task;
-
- volatile int ai_control_task_flag; /**< Flag controling reexecuting of control task */
-
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me4600_ai_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-4000 analog input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param channels The number of analog input channels available on this subdevice.
- * @param channels The number of analog input ranges available on this subdevice.
- * @param isolated Flag indicating if this device is opto isolated.
- * @param sh Flag indicating if sample and hold devices are available.
- * @param irq The irq number assigned by PCI BIOS.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base,
- unsigned int channels,
- unsigned int ranges,
- int isolated,
- int sh,
- int irq,
- spinlock_t * ctrl_reg_lock,
- struct workqueue_struct
- *me4600_wq);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_ai_reg.h b/drivers/staging/meilhaus/me4600_ai_reg.h
deleted file mode 100644
index 083fac7..0000000
--- a/drivers/staging/meilhaus/me4600_ai_reg.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * @file me4600_ai_reg.h
- *
- * @brief ME-4000 analog input subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_AI_REG_H_
-#define _ME4600_AI_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME4600_AI_CTRL_REG 0x74 // _/W
-#define ME4600_AI_STATUS_REG 0x74 // R/_
-#define ME4600_AI_CHANNEL_LIST_REG 0x78 // _/W
-#define ME4600_AI_DATA_REG 0x7C // R/_
-#define ME4600_AI_CHAN_TIMER_REG 0x80 // _/W
-#define ME4600_AI_CHAN_PRE_TIMER_REG 0x84 // _/W
-#define ME4600_AI_SCAN_TIMER_LOW_REG 0x88 // _/W
-#define ME4600_AI_SCAN_TIMER_HIGH_REG 0x8C // _/W
-#define ME4600_AI_SCAN_PRE_TIMER_LOW_REG 0x90 // _/W
-#define ME4600_AI_SCAN_PRE_TIMER_HIGH_REG 0x94 // _/W
-#define ME4600_AI_START_REG 0x98 // R/_
-
-#define ME4600_AI_SAMPLE_COUNTER_REG 0xC0 // _/W
-
-#define ME4600_AI_CTRL_BIT_MODE_0 0x00000001
-#define ME4600_AI_CTRL_BIT_MODE_1 0x00000002
-#define ME4600_AI_CTRL_BIT_MODE_2 0x00000004
-#define ME4600_AI_CTRL_BIT_SAMPLE_HOLD 0x00000008
-#define ME4600_AI_CTRL_BIT_IMMEDIATE_STOP 0x00000010
-#define ME4600_AI_CTRL_BIT_STOP 0x00000020
-#define ME4600_AI_CTRL_BIT_CHANNEL_FIFO 0x00000040
-#define ME4600_AI_CTRL_BIT_DATA_FIFO 0x00000080
-#define ME4600_AI_CTRL_BIT_FULLSCALE 0x00000100
-#define ME4600_AI_CTRL_BIT_OFFSET 0x00000200
-#define ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG 0x00000400
-#define ME4600_AI_CTRL_BIT_EX_TRIG 0x00000800
-#define ME4600_AI_CTRL_BIT_EX_TRIG_FALLING 0x00001000
-#define ME4600_AI_CTRL_BIT_EX_IRQ 0x00002000
-#define ME4600_AI_CTRL_BIT_EX_IRQ_RESET 0x00004000
-#define ME4600_AI_CTRL_BIT_LE_IRQ 0x00008000
-#define ME4600_AI_CTRL_BIT_LE_IRQ_RESET 0x00010000
-#define ME4600_AI_CTRL_BIT_HF_IRQ 0x00020000
-#define ME4600_AI_CTRL_BIT_HF_IRQ_RESET 0x00040000
-#define ME4600_AI_CTRL_BIT_SC_IRQ 0x00080000
-#define ME4600_AI_CTRL_BIT_SC_IRQ_RESET 0x00100000
-#define ME4600_AI_CTRL_BIT_SC_RELOAD 0x00200000
-#define ME4600_AI_CTRL_BIT_EX_TRIG_BOTH 0x80000000
-
-#define ME4600_AI_STATUS_BIT_EF_CHANNEL 0x00400000
-#define ME4600_AI_STATUS_BIT_HF_CHANNEL 0x00800000
-#define ME4600_AI_STATUS_BIT_FF_CHANNEL 0x01000000
-#define ME4600_AI_STATUS_BIT_EF_DATA 0x02000000
-#define ME4600_AI_STATUS_BIT_HF_DATA 0x04000000
-#define ME4600_AI_STATUS_BIT_FF_DATA 0x08000000
-#define ME4600_AI_STATUS_BIT_LE 0x10000000
-#define ME4600_AI_STATUS_BIT_FSM 0x20000000
-
-#define ME4600_AI_CTRL_RPCI_FIFO 0x40000000 //Always set to zero!
-
-#define ME4600_AI_BASE_FREQUENCY 33E6
-
-#define ME4600_AI_MIN_ACQ_TICKS 66LL
-#define ME4600_AI_MAX_ACQ_TICKS 0xFFFFFFFFLL
-
-#define ME4600_AI_MIN_SCAN_TICKS 66LL
-#define ME4600_AI_MAX_SCAN_TICKS 0xFFFFFFFFFLL
-
-#define ME4600_AI_MIN_CHAN_TICKS 66LL
-#define ME4600_AI_MAX_CHAN_TICKS 0xFFFFFFFFLL
-
-#define ME4600_AI_FIFO_COUNT 2048
-
-#define ME4600_AI_LIST_COUNT 1024
-
-#define ME4600_AI_LIST_INPUT_SINGLE_ENDED 0x000
-#define ME4600_AI_LIST_INPUT_DIFFERENTIAL 0x020
-
-#define ME4600_AI_LIST_RANGE_BIPOLAR_10 0x000
-#define ME4600_AI_LIST_RANGE_BIPOLAR_2_5 0x040
-#define ME4600_AI_LIST_RANGE_UNIPOLAR_10 0x080
-#define ME4600_AI_LIST_RANGE_UNIPOLAR_2_5 0x0C0
-
-#define ME4600_AI_LIST_LAST_ENTRY 0x100
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_ao.c b/drivers/staging/meilhaus/me4600_ao.c
deleted file mode 100644
index 4000dac..0000000
--- a/drivers/staging/meilhaus/me4600_ao.c
+++ /dev/null
@@ -1,5974 +0,0 @@
-/**
- * @file me4600_ao.c
- *
- * @brief ME-4000 analog output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-///Common part. (For normal and Bosch builds.)
-
-/* Includes
- */
-
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <linux/types.h>
-#include <linux/version.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "meids.h"
-#include "me4600_reg.h"
-#include "me4600_ao_reg.h"
-#include "me4600_ao.h"
-
-/* Defines
- */
-
-static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
- int unit,
- int *min,
- int *max, int *maxdata, int *range);
-
-static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice,
- int unit, int *count);
-
-static int me4600_ao_query_range_info(me_subdevice_t *subdevice,
- int range,
- int *unit,
- int *min, int *max, int *maxdata);
-
-static int me4600_ao_query_timer(me_subdevice_t *subdevice,
- int timer,
- int *base_frequency,
- long long *min_ticks, long long *max_ticks);
-
-static int me4600_ao_query_number_channels(me_subdevice_t *subdevice,
- int *number);
-
-static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype);
-
-static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps);
-
-static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
- int cap, int *args, int count);
-
-#ifndef BOSCH
-/// @note NORMAL BUILD
-/// @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
-/* Includes
- */
-
-# include <linux/workqueue.h>
-
-/* Defines
- */
-
-/** Remove subdevice.
-*/
-static void me4600_ao_destructor(struct me_subdevice *subdevice);
-
-/** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'.
-*/
-static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
- struct file *filep, int flags);
-
-/** Set output as single
-*/
-static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags);
-
-/** Pass to user actual value of output.
-*/
-static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags);
-
-/** Write to output requed value.
-*/
-static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags);
-
-/** Set output as streamed device.
-*/
-static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
- struct file *filep,
- meIOStreamConfig_t *config_list,
- int count,
- meIOStreamTrigger_t *trigger,
- int fifo_irq_threshold, int flags);
-
-/** Wait for / Check empty space in buffer.
-*/
-static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
- struct file *filep,
- int time_out, int *count, int flags);
-
-/** Start streaming.
-*/
-static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
- struct file *filep,
- int start_mode, int time_out, int flags);
-
-/** Check actual state. / Wait for end.
-*/
-static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
- struct file *filep,
- int wait,
- int *status, int *values, int flags);
-
-/** Stop streaming.
-*/
-static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
- struct file *filep,
- int stop_mode, int flags);
-
-/** Write datas to buffor.
-*/
-static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
- struct file *filep,
- int write_mode,
- int *values, int *count, int flags);
-
-/** Interrupt handler. Copy from buffer to FIFO.
-*/
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id);
-/** Copy data from circular buffer to fifo (fast) in wraparound mode.
-*/
-inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count,
- int start_pos);
-
-/** Copy data from circular buffer to fifo (fast).
-*/
-inline int ao_write_data(me4600_ao_subdevice_t *instance, int count,
- int start_pos);
-
-/** Copy data from circular buffer to fifo (slow).
-*/
-inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count,
- int start_pos);
-
-/** Copy data from user space to circular buffer.
-*/
-inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count,
- int *user_values);
-
-/** Stop presentation. Preserve FIFOs.
-*/
-inline int ao_stop_immediately(me4600_ao_subdevice_t *instance);
-
-/** Task for asynchronical state verifying.
-*/
-static void me4600_ao_work_control_task(struct work_struct *work);
-/* Functions
- */
-
-static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
- struct file *filep, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t tmp;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- instance->status = ao_status_none;
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
- instance->timeout.delay = 0;
- instance->timeout.start_time = jiffies;
-
- //Stop state machine.
- err = ao_stop_immediately(instance);
-
- //Remove from synchronous start.
- spin_lock(instance->preload_reg_lock);
- tmp = inl(instance->preload_reg);
- tmp &=
- ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->
- ao_idx);
- outl(tmp, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->preload_reg - instance->reg_base, tmp);
- *instance->preload_flags &=
- ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->
- ao_idx);
- spin_unlock(instance->preload_reg_lock);
-
- //Set single mode, dissable FIFO, dissable external trigger, set output to analog, block interrupt.
- outl(ME4600_AO_MODE_SINGLE | ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_RESET_IRQ,
- instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ME4600_AO_MODE_SINGLE | ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
- ME4600_AO_CTRL_BIT_RESET_IRQ);
-
- //Set output to 0V
- outl(0x8000, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->single_reg - instance->reg_base, 0x8000);
-
- instance->circ_buf.head = 0;
- instance->circ_buf.tail = 0;
- instance->preloaded_count = 0;
- instance->data_count = 0;
- instance->single_value = 0x8000;
- instance->single_value_in_fifo = 0x8000;
-
- //Set status to signal that device is unconfigured.
- instance->status = ao_status_none;
-
- //Signal reset if user is on wait.
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t ctrl;
- uint32_t sync;
- unsigned long cpu_flags;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- // Checking parameters
- if (flags) {
- PERROR
- ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- switch (trig_type) {
- case ME_TRIG_TYPE_SW:
- if (trig_edge != ME_TRIG_EDGE_NONE) {
- PERROR
- ("Invalid trigger edge. Software trigger has not edge.\n");
- return ME_ERRNO_INVALID_TRIG_EDGE;
- }
- break;
-
- case ME_TRIG_TYPE_EXT_DIGITAL:
- switch (trig_edge) {
- case ME_TRIG_EDGE_ANY:
- case ME_TRIG_EDGE_RISING:
- case ME_TRIG_EDGE_FALLING:
- break;
-
- default:
- PERROR("Invalid trigger edge.\n");
- return ME_ERRNO_INVALID_TRIG_EDGE;
- }
- break;
-
- default:
- PERROR
- ("Invalid trigger type. Trigger must be software or digital.\n");
- return ME_ERRNO_INVALID_TRIG_TYPE;
- }
-
- if ((trig_chan != ME_TRIG_CHAN_DEFAULT)
- && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) {
- PERROR("Invalid trigger channel specified.\n");
- return ME_ERRNO_INVALID_TRIG_CHAN;
- }
-
- if (ref != ME_REF_AO_GROUND) {
- PERROR
- ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n");
- return ME_ERRNO_INVALID_REF;
- }
-
- if (single_config != 0) {
- PERROR
- ("Invalid single config specified. Only one range for anlog outputs is available.\n");
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
-
- if (channel != 0) {
- PERROR
- ("Invalid channel number specified. Analog output have only one channel.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- //Subdevice running in stream mode!
- if ((instance->status >= ao_status_stream_run_wait)
- && (instance->status < ao_status_stream_end)) {
- PERROR("Subdevice is busy.\n");
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
-/// @note For single all calls (config and write) are erasing previous state!
-
- instance->status = ao_status_none;
-
- // Correct single mirrors
- instance->single_value_in_fifo = instance->single_value;
-
- //Stop device
- err = ao_stop_immediately(instance);
- if (err) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
- // Set control register.
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- // Set stop bit. Stop streaming mode.
- ctrl = inl(instance->ctrl_reg);
- //Reset all bits.
- ctrl = ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP;
-
- if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) {
- PINFO("External digital trigger.\n");
-
- if (trig_edge == ME_TRIG_EDGE_ANY) {
-// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
- instance->ctrl_trg =
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
- } else if (trig_edge == ME_TRIG_EDGE_FALLING) {
-// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
- instance->ctrl_trg = ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
- } else if (trig_edge == ME_TRIG_EDGE_RISING) {
- instance->ctrl_trg = 0x0;
- }
- } else if (trig_type == ME_TRIG_TYPE_SW) {
- PDEBUG("Software trigger\n");
- instance->ctrl_trg = 0x0;
- }
-
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- // Set preload/synchronization register.
- spin_lock(instance->preload_reg_lock);
- if (trig_type == ME_TRIG_TYPE_SW) {
- *instance->preload_flags &=
- ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx);
- } else //if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL)
- {
- *instance->preload_flags |=
- ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx;
- }
-
- if (trig_chan == ME_TRIG_CHAN_DEFAULT) {
- *instance->preload_flags &=
- ~(ME4600_AO_SYNC_HOLD << instance->ao_idx);
- } else //if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS)
- {
- *instance->preload_flags |=
- ME4600_AO_SYNC_HOLD << instance->ao_idx;
- }
-
- //Reset hardware register
- sync = inl(instance->preload_reg);
- PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->preload_reg - instance->reg_base, sync);
- sync &= ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx);
- sync |= ME4600_AO_SYNC_HOLD << instance->ao_idx;
-
- //Output configured in default (safe) mode.
- outl(sync, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->preload_reg - instance->reg_base, sync);
- spin_unlock(instance->preload_reg_lock);
-
- instance->status = ao_status_single_configured;
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- unsigned long j;
- unsigned long delay = 0;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags & ~ME_IO_SINGLE_NONBLOCKING) {
- PERROR("Invalid flag specified. %d\n", flags);
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (channel != 0) {
- PERROR("Invalid channel number specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if ((instance->status >= ao_status_stream_configured)
- && (instance->status <= ao_status_stream_end)) {
- PERROR("Subdevice not configured to work in single mode!\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-
- ME_SUBDEVICE_ENTER;
- if ((!flags) && (instance->status == ao_status_single_run_wait)) { //Blocking mode. Wait for trigger.
- if (time_out) {
- delay = (time_out * HZ) / 1000;
- if (delay == 0)
- delay = 1;
- }
-
- j = jiffies;
-
- //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
- wait_event_interruptible_timeout(instance->wait_queue,
- (instance->status !=
- ao_status_single_run_wait),
- (delay) ? delay +
- 1 : LONG_MAX);
-
- if (instance->status == ao_status_none) {
- PDEBUG("Single canceled.\n");
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on start of state machine interrupted.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- }
-
- if ((delay) && ((jiffies - j) >= delay)) {
-
- PDEBUG("Timeout reached.\n");
- err = ME_ERRNO_TIMEOUT;
- }
-
- *value =
- (!err) ? instance->single_value_in_fifo : instance->
- single_value;
- } else { //Non-blocking mode
- //Read value
- *value = instance->single_value;
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long cpu_flags;
- unsigned long j;
- unsigned long delay = 0x0;
-
- //Registry handling variables.
- uint32_t sync_mask;
- uint32_t mode;
- uint32_t tmp;
- uint32_t ctrl;
- uint32_t status;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags &
- ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS |
- ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (value & ~ME4600_AO_MAX_DATA) {
- PERROR("Invalid value provided.\n");
- return ME_ERRNO_VALUE_OUT_OF_RANGE;
- }
-
- if (channel != 0) {
- PERROR("Invalid channel number specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if ((instance->status == ao_status_none)
- || (instance->status > ao_status_single_end)) {
- PERROR("Subdevice not configured to work in single mode!\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-
- ME_SUBDEVICE_ENTER;
-
-/// @note For single all calls (config and write) are erasing previous state!
-
- //Cancel control task
- PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
-
- // Correct single mirrors
- instance->single_value_in_fifo = instance->single_value;
-
- //Stop device
- err = ao_stop_immediately(instance);
- if (err) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
-
- if (time_out) {
- delay = (time_out * HZ) / 1000;
-
- if (delay == 0)
- delay = 1;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
- instance->single_value_in_fifo = value;
-
- ctrl = inl(instance->ctrl_reg);
-
- if (!instance->fifo) { //No FIFO
- //Set the single mode.
- ctrl &= ~ME4600_AO_CTRL_MODE_MASK;
-
- //Write value
- PDEBUG("Write value\n");
- outl(value, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base, value);
- } else { // mix-mode
- //Set speed
- outl(ME4600_AO_MIN_CHAN_TICKS - 1, instance->timer_reg);
- PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->timer_reg - instance->reg_base,
- (int)ME4600_AO_MIN_CHAN_TICKS);
- instance->hardware_stop_delay = HZ / 10; //100ms
-
- status = inl(instance->status_reg);
-
- //Set the continous mode.
- ctrl &= ~ME4600_AO_CTRL_MODE_MASK;
- ctrl |= ME4600_AO_MODE_CONTINUOUS;
-
- //Prepare FIFO
- if (!(ctrl & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO wasn't enabeled. Do it.
- PINFO("Enableing FIFO.\n");
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- ctrl |=
- ME4600_AO_CTRL_BIT_ENABLE_FIFO |
- ME4600_AO_CTRL_BIT_RESET_IRQ;
- } else { //Check if FIFO is empty
- if (status & ME4600_AO_STATUS_BIT_EF) { //FIFO not empty
- PINFO("Reseting FIFO.\n");
- ctrl &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_FIFO |
- ME4600_AO_CTRL_BIT_ENABLE_IRQ);
- ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg -
- instance->reg_base, ctrl);
-
- ctrl |=
- ME4600_AO_CTRL_BIT_ENABLE_FIFO |
- ME4600_AO_CTRL_BIT_RESET_IRQ;
- } else { //FIFO empty, only interrupt needs to be disabled!
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
- }
- }
-
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- //Write output - 1 value to FIFO
- if (instance->ao_idx & 0x1) {
- outl(value <<= 16, instance->fifo_reg);
- PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->fifo_reg - instance->reg_base,
- value <<= 16);
- } else {
- outl(value, instance->fifo_reg);
- PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->fifo_reg - instance->reg_base,
- value);
- }
- }
-
- mode = *instance->preload_flags >> instance->ao_idx;
- mode &= (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG);
-
- PINFO("Triggering mode: 0x%x\n", mode);
-
- spin_lock(instance->preload_reg_lock);
- sync_mask = inl(instance->preload_reg);
- PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->preload_reg - instance->reg_base, sync_mask);
- switch (mode) {
- case 0: //Individual software
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
- if (!instance->fifo) { // No FIFO - In this case resetting 'ME4600_AO_SYNC_HOLD' will trigger output.
- 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.
- sync_mask &=
- ~(ME4600_AO_SYNC_EXT_TRIG << instance->
- ao_idx);
- sync_mask |=
- ME4600_AO_SYNC_HOLD << instance->ao_idx;
-
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG
- ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- } else { // FIFO
- if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode.
- sync_mask &=
- ~((ME4600_AO_SYNC_EXT_TRIG |
- ME4600_AO_SYNC_HOLD) << instance->
- ao_idx);
-
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG
- ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- }
- instance->single_value = value;
- break;
-
- case ME4600_AO_SYNC_EXT_TRIG: //Individual hardware
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
- if (!instance->fifo) { // No FIFO - In this case resetting 'ME4600_AO_SYNC_HOLD' will trigger output.
- 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
- sync_mask &=
- ~(ME4600_AO_SYNC_EXT_TRIG << instance->
- ao_idx);
- sync_mask |=
- ME4600_AO_SYNC_HOLD << instance->ao_idx;
-
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG
- ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- } else { // FIFO
- if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode.
- sync_mask &=
- ~((ME4600_AO_SYNC_EXT_TRIG |
- ME4600_AO_SYNC_HOLD) << instance->
- ao_idx);
-
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG
- ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- }
- break;
-
- case ME4600_AO_SYNC_HOLD: //Synchronous software
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
-// if((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME4600_AO_SYNC_HOLD)
- 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
- sync_mask |=
- ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx;
-// sync_mask &= ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx);
- sync_mask |= ME4600_AO_SYNC_HOLD << instance->ao_idx;
-
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- break;
-
- case (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG): //Synchronous hardware
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
- 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
- sync_mask |=
- (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) <<
- instance->ao_idx;
-
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- break;
- }
-// spin_unlock(instance->preload_reg_lock); // Moved down.
-
- //Activate ISM (remove 'stop' bits)
- ctrl &=
- ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
- ctrl |= instance->ctrl_trg;
- ctrl &= ~(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-/// @note When flag 'ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS' is set than output is triggered. ALWAYS!
-
- if (!instance->fifo) { //No FIFO
- if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Fired all software synchronous outputs.
- tmp = ~(*instance->preload_flags | 0xFFFF0000);
- PINFO
- ("Fired all software synchronous outputs. mask:0x%08x\n",
- tmp);
- tmp |= sync_mask & 0xFFFF0000;
- // Add this channel to list
- tmp &= ~(ME4600_AO_SYNC_HOLD << instance->ao_idx);
-
- //Fire
- PINFO("Software trigger.\n");
- outl(tmp, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- tmp);
-
- //Restore save settings
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- } else if (!mode) { // Add this channel to list
- outl(sync_mask &
- ~(ME4600_AO_SYNC_HOLD << instance->ao_idx),
- instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask & ~(ME4600_AO_SYNC_HOLD <<
- instance->ao_idx));
-
- //Fire
- PINFO("Software trigger.\n");
-
- //Restore save settings
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
-
- } else { // mix-mode - begin
- if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs
- //Add channel to start list
- outl(sync_mask |
- (ME4600_AO_SYNC_HOLD << instance->ao_idx),
- instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask | (ME4600_AO_SYNC_HOLD <<
- instance->ao_idx));
-
- //Fire
- PINFO
- ("Fired all software synchronous outputs by software trigger.\n");
- outl(0x8000, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base,
- 0x8000);
-
- //Restore save settings
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- } else if (!mode) { //Trigger outputs
-/* //Remove channel from start list //<== Unnecessary. Removed.
- outl(sync_mask & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, tmp);
-*/
- //Fire
- PINFO("Software trigger.\n");
- outl(0x8000, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base,
- 0x8000);
-
-/* //Restore save settings //<== Unnecessary. Removed.
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask);
-*/
- }
- }
- spin_unlock(instance->preload_reg_lock);
-
- j = jiffies;
- instance->status = ao_status_single_run_wait;
-
- instance->timeout.delay = delay;
- instance->timeout.start_time = j;
- instance->ao_control_task_flag = 1;
- queue_delayed_work(instance->me4600_workqueue,
- &instance->ao_control_task, 1);
-
- if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
-
- //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
- wait_event_interruptible_timeout(instance->wait_queue,
- (instance->status !=
- ao_status_single_run_wait),
- (delay) ? delay +
- 1 : LONG_MAX);
-
- if (((!delay) || ((jiffies - j) <= delay))
- && (instance->status != ao_status_single_end)) {
- PDEBUG("Single canceled.\n");
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on start of state machine interrupted.\n");
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
- ao_stop_immediately(instance);
- instance->status = ao_status_none;
- err = ME_ERRNO_SIGNAL;
- }
-
- if ((delay) && ((jiffies - j) >= delay)) {
- if (instance->status == ao_status_single_end) {
- PDEBUG("Timeout reached.\n");
- } else {
- if ((jiffies - j) > delay) {
- PERROR
- ("Timeout reached. Not handled by control task!\n");
- } else {
- PERROR
- ("Timeout reached. Signal come but status is strange: %d\n",
- instance->status);
- }
-
- ao_stop_immediately(instance);
- }
-
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
- instance->status = ao_status_single_end;
- err = ME_ERRNO_TIMEOUT;
- }
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
- struct file *filep,
- meIOStreamConfig_t *config_list,
- int count,
- meIOStreamTrigger_t *trigger,
- int fifo_irq_threshold, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t ctrl;
- unsigned long cpu_flags;
- uint64_t conv_ticks;
- unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
- unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- conv_ticks =
- (uint64_t) conv_start_ticks_low +
- ((uint64_t) conv_start_ticks_high << 32);
-
- if (flags &
- ~(ME_IO_STREAM_CONFIG_HARDWARE_ONLY | ME_IO_STREAM_CONFIG_WRAPAROUND
- | ME_IO_STREAM_CONFIG_BIT_PATTERN)) {
- PERROR("Invalid flags.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
- if (!(flags & ME_IO_STREAM_CONFIG_WRAPAROUND)) {
- PERROR
- ("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((trigger->iAcqStopTrigType != ME_TRIG_TYPE_NONE)
- || (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE)) {
- PERROR
- ("Hardware wraparound mode must be in infinite mode.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
- }
-
- if (count != 1) {
- PERROR("Only 1 entry in config list acceptable.\n");
- return ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
- }
-
- if (config_list[0].iChannel != 0) {
- PERROR("Invalid channel number specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (config_list[0].iStreamConfig != 0) {
- PERROR("Only one range available.\n");
- return ME_ERRNO_INVALID_STREAM_CONFIG;
- }
-
- if (config_list[0].iRef != ME_REF_AO_GROUND) {
- PERROR("Output is referenced to ground.\n");
- return ME_ERRNO_INVALID_REF;
- }
-
- if ((trigger->iAcqStartTicksLow != 0)
- || (trigger->iAcqStartTicksHigh != 0)) {
- PERROR
- ("Invalid acquisition start trigger argument specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_ARG;
- }
-
- if (config_list[0].iFlags) {
- PERROR("Invalid config list flag.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- switch (trigger->iAcqStartTrigType) {
- case ME_TRIG_TYPE_SW:
- if (trigger->iAcqStartTrigEdge != ME_TRIG_EDGE_NONE) {
- PERROR
- ("Invalid acquisition start trigger edge specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
- }
- break;
-
- case ME_TRIG_TYPE_EXT_DIGITAL:
- switch (trigger->iAcqStartTrigEdge) {
- case ME_TRIG_EDGE_ANY:
- case ME_TRIG_EDGE_RISING:
- case ME_TRIG_EDGE_FALLING:
- break;
-
- default:
- PERROR
- ("Invalid acquisition start trigger edge specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
- }
- break;
-
- default:
- PERROR("Invalid acquisition start trigger type specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
- }
-
- if (trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW) {
- PERROR("Invalid scan start trigger type specified.\n");
- return ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
- }
-
- if (trigger->iConvStartTrigType != ME_TRIG_TYPE_TIMER) {
- PERROR("Invalid conv start trigger type specified.\n");
- return ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
- }
-
- if ((conv_ticks < ME4600_AO_MIN_CHAN_TICKS)
- || (conv_ticks > ME4600_AO_MAX_CHAN_TICKS)) {
- PERROR("Invalid conv start trigger argument specified.\n");
- return ME_ERRNO_INVALID_CONV_START_ARG;
- }
-
- if (trigger->iAcqStartTicksLow || trigger->iAcqStartTicksHigh) {
- PERROR("Invalid acq start trigger argument specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_ARG;
- }
-
- if (trigger->iScanStartTicksLow || trigger->iScanStartTicksHigh) {
- PERROR("Invalid scan start trigger argument specified.\n");
- return ME_ERRNO_INVALID_SCAN_START_ARG;
- }
-
- switch (trigger->iScanStopTrigType) {
- case ME_TRIG_TYPE_NONE:
- if (trigger->iScanStopCount != 0) {
- PERROR("Invalid scan stop count specified.\n");
- return ME_ERRNO_INVALID_SCAN_STOP_ARG;
- }
- break;
-
- case ME_TRIG_TYPE_COUNT:
- if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
- if (trigger->iScanStopCount <= 0) {
- PERROR("Invalid scan stop count specified.\n");
- return ME_ERRNO_INVALID_SCAN_STOP_ARG;
- }
- } else {
- PERROR("The continous mode has not 'scan' contects.\n");
- return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- }
- break;
-
- default:
- PERROR("Invalid scan stop trigger type specified.\n");
- return ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
- }
-
- switch (trigger->iAcqStopTrigType) {
- case ME_TRIG_TYPE_NONE:
- if (trigger->iAcqStopCount != 0) {
- PERROR("Invalid acq stop count specified.\n");
- return ME_ERRNO_INVALID_ACQ_STOP_ARG;
- }
- break;
-
- case ME_TRIG_TYPE_COUNT:
- if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
- PERROR("Invalid acq stop trigger type specified.\n");
- return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- }
-
- if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
- if (trigger->iAcqStopCount <= 0) {
- PERROR
- ("The continous mode has not 'scan' contects.\n");
- return ME_ERRNO_INVALID_ACQ_STOP_ARG;
- }
- }
- break;
-
- default:
- PERROR("Invalid acq stop trigger type specified.\n");
- return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- }
-
- switch (trigger->iAcqStartTrigChan) {
- case ME_TRIG_CHAN_DEFAULT:
- case ME_TRIG_CHAN_SYNCHRONOUS:
- break;
-
- default:
- PERROR("Invalid acq start trigger channel specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if ((flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) && !instance->bitpattern) {
- PERROR("This subdevice not support output redirection.\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INVALID_FLAGS;
- }
- //Stop device
-
- //Cancel control task
- PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
-
- //Check if state machine is stopped.
- err = ao_stop_immediately(instance);
- if (err) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- //Reset control register. Block all actions. Disable IRQ. Disable FIFO.
- ctrl =
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- //This is paranoic, but to be sure.
- instance->preloaded_count = 0;
- instance->data_count = 0;
- instance->circ_buf.head = 0;
- instance->circ_buf.tail = 0;
-
- /* Set mode. */
- if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { //Wraparound
- if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) { //Hardware wraparound
- PINFO("Hardware wraparound.\n");
- ctrl |= ME4600_AO_MODE_WRAPAROUND;
- instance->mode = ME4600_AO_HW_WRAP_MODE;
- } else { //Software wraparound
- PINFO("Software wraparound.\n");
- ctrl |= ME4600_AO_MODE_CONTINUOUS;
- instance->mode = ME4600_AO_SW_WRAP_MODE;
- }
- } else { //Continous
- PINFO("Continous.\n");
- ctrl |= ME4600_AO_MODE_CONTINUOUS;
- instance->mode = ME4600_AO_CONTINOUS;
- }
-
- //Set the trigger edge.
- if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Set the trigger type and edge for external trigger.
- PINFO("External digital trigger.\n");
- instance->start_mode = ME4600_AO_EXT_TRIG;
-/*
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-*/
- switch (trigger->iAcqStartTrigEdge) {
- case ME_TRIG_EDGE_RISING:
- PINFO("Set the trigger edge: rising.\n");
- instance->ctrl_trg = 0x0;
- break;
-
- case ME_TRIG_EDGE_FALLING:
- PINFO("Set the trigger edge: falling.\n");
-// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
- instance->ctrl_trg = ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
- break;
-
- case ME_TRIG_EDGE_ANY:
- PINFO("Set the trigger edge: both edges.\n");
-// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
- instance->ctrl_trg =
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
- break;
- }
- } else {
- PINFO("Internal software trigger.\n");
- instance->start_mode = 0;
- }
-
- //Set the stop mode and value.
- if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of data
- instance->stop_mode = ME4600_AO_ACQ_STOP_MODE;
- instance->stop_count = trigger->iAcqStopCount;
- } else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of 'scans'
- instance->stop_mode = ME4600_AO_SCAN_STOP_MODE;
- instance->stop_count = trigger->iScanStopCount;
- } else { //Infinite
- instance->stop_mode = ME4600_AO_INF_STOP_MODE;
- instance->stop_count = 0;
- }
-
- PINFO("Stop count: %d.\n", instance->stop_count);
-
- if (trigger->iAcqStartTrigChan == ME_TRIG_CHAN_SYNCHRONOUS) { //Synchronous start
- instance->start_mode |= ME4600_AO_SYNC_HOLD;
- if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Externaly triggered
- PINFO("Synchronous start. Externaly trigger active.\n");
- instance->start_mode |= ME4600_AO_SYNC_EXT_TRIG;
- }
-#ifdef MEDEBUG_INFO
- else {
- PINFO
- ("Synchronous start. Externaly trigger dissabled.\n");
- }
-#endif
-
- }
- //Set speed
- outl(conv_ticks - 2, instance->timer_reg);
- PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%llx\n", instance->reg_base,
- instance->timer_reg - instance->reg_base, conv_ticks - 2);
- instance->hardware_stop_delay = (int)(conv_ticks * HZ) / ME4600_AO_BASE_FREQUENCY; //<== MUST be with cast!
-
- //Conect outputs to analog or digital port.
- if (flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) {
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_DO;
- }
- // Write the control word
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- //Set status.
- instance->status = ao_status_stream_configured;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
- struct file *filep,
- int time_out, int *count, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- long t = 0;
- long j;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (!instance->circ_buf.buf) {
- PERROR("Circular buffer not exists.\n");
- return ME_ERRNO_INTERNAL;
- }
-
- if (time_out < 0) {
- PERROR("Invalid time_out specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (me_circ_buf_space(&instance->circ_buf)) { //The buffer is NOT full.
- *count = me_circ_buf_space(&instance->circ_buf);
- } else { //The buffer is full.
- if (time_out) {
- t = (time_out * HZ) / 1000;
-
- if (t == 0)
- t = 1;
- } else { //Max time.
- t = LONG_MAX;
- }
-
- *count = 0;
-
- j = jiffies;
-
- //Only runing process will interrupt this call. Interrupts are when FIFO HF is signaled.
- wait_event_interruptible_timeout(instance->wait_queue,
- ((me_circ_buf_space
- (&instance->circ_buf))
- || !(inl(instance->status_reg)
- &
- ME4600_AO_STATUS_BIT_FSM)),
- t);
-
- if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
- PERROR("AO subdevice is not running.\n");
- err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
- } else if (signal_pending(current)) {
- PERROR("Wait on values interrupted from signal.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- } else if ((jiffies - j) >= t) {
- PERROR("Wait on values timed out.\n");
- err = ME_ERRNO_TIMEOUT;
- } else { //Uff... all is good. Inform user about empty space.
- *count = me_circ_buf_space(&instance->circ_buf);
- }
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
- struct file *filep,
- int start_mode, int time_out, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long cpu_flags = 0;
- uint32_t status;
- uint32_t ctrl;
- uint32_t synch;
- int count = 0;
- int circ_buffer_count;
-
- unsigned long ref;
- unsigned long delay = 0;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (flags & ~ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
- PERROR("Invalid flags.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if ((start_mode != ME_START_MODE_BLOCKING)
- && (start_mode != ME_START_MODE_NONBLOCKING)) {
- PERROR("Invalid start mode specified.\n");
- return ME_ERRNO_INVALID_START_MODE;
- }
-
- if (time_out) {
- delay = (time_out * HZ) / 1000;
- if (delay == 0)
- delay = 1;
- }
-
- switch (instance->status) { //Checking actual mode.
- case ao_status_stream_configured:
- case ao_status_stream_end:
- //Correct modes!
- break;
-
- //The device is in wrong mode.
- case ao_status_none:
- case ao_status_single_configured:
- case ao_status_single_run_wait:
- case ao_status_single_run:
- case ao_status_single_end_wait:
- PERROR
- ("Subdevice must be preinitialize correctly for streaming.\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
-
- case ao_status_stream_fifo_error:
- case ao_status_stream_buffer_error:
- case ao_status_stream_error:
- PDEBUG("Before restart broke stream 'STOP' must be caled.\n");
- return ME_STATUS_ERROR;
-
- case ao_status_stream_run_wait:
- case ao_status_stream_run:
- case ao_status_stream_end_wait:
- PDEBUG("Stream is already working.\n");
- return ME_ERRNO_SUBDEVICE_BUSY;
-
- default:
- instance->status = ao_status_stream_error;
- PERROR_CRITICAL("Status is in wrong state!\n");
- return ME_ERRNO_INTERNAL;
-
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (instance->mode == ME4600_AO_CONTINOUS) { //Continous
- instance->circ_buf.tail += instance->preloaded_count;
- instance->circ_buf.tail &= instance->circ_buf.mask;
- }
- circ_buffer_count = me_circ_buf_values(&instance->circ_buf);
-
- if (!circ_buffer_count && !instance->preloaded_count) { //No values in buffer
- ME_SUBDEVICE_EXIT;
- PERROR("No values in buffer!\n");
- return ME_ERRNO_LACK_OF_RESOURCES;
- }
-
- //Cancel control task
- PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
-
- //Stop device
- err = ao_stop_immediately(instance);
- if (err) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
- //Set values for single_read()
- instance->single_value = ME4600_AO_MAX_DATA + 1;
- instance->single_value_in_fifo = ME4600_AO_MAX_DATA + 1;
-
- //Setting stop points
- if (instance->stop_mode == ME4600_AO_SCAN_STOP_MODE) {
- instance->stop_data_count =
- instance->stop_count * circ_buffer_count;
- } else {
- instance->stop_data_count = instance->stop_count;
- }
-
- if ((instance->stop_data_count != 0)
- && (instance->stop_data_count < circ_buffer_count)) {
- PERROR("More data in buffer than previously set limit!\n");
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- //Check FIFO
- 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
- PINFO("Enableing FIFO.\n");
- ctrl |=
- ME4600_AO_CTRL_BIT_ENABLE_FIFO |
- ME4600_AO_CTRL_BIT_RESET_IRQ;
-
- instance->preloaded_count = 0;
- instance->data_count = 0;
- } else { //Block IRQ
- ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
- }
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl | ME4600_AO_CTRL_BIT_RESET_IRQ);
-
- //Fill FIFO <= Generaly this should be done by user pre-load call but this is second place to do it.
- status = inl(instance->status_reg);
- if (!(status & ME4600_AO_STATUS_BIT_EF)) { //FIFO empty
- if (instance->stop_data_count == 0) {
- count = ME4600_AO_FIFO_COUNT;
- } else {
- count =
- (ME4600_AO_FIFO_COUNT <
- instance->
- stop_data_count) ? ME4600_AO_FIFO_COUNT :
- instance->stop_data_count;
- }
-
- //Copy data
- count =
- ao_write_data(instance, count, instance->preloaded_count);
-
- if (count < 0) { //This should never happend!
- PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
- }
- //Set pre-load features.
- spin_lock(instance->preload_reg_lock);
- synch = inl(instance->preload_reg);
- synch &=
- ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->
- ao_idx);
- synch |=
- (instance->start_mode & ~ME4600_AO_EXT_TRIG) << instance->ao_idx;
- outl(synch, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->preload_reg - instance->reg_base, synch);
- spin_unlock(instance->preload_reg_lock);
-
- //Default count is '0'
- if (instance->mode == ME4600_AO_CONTINOUS) { //Continous
- instance->preloaded_count = 0;
- instance->circ_buf.tail += count;
- instance->circ_buf.tail &= instance->circ_buf.mask;
- } else { //Wraparound
- instance->preloaded_count += count;
- instance->data_count += count;
-
- //Special case: Infinite wraparound with less than FIFO datas always should runs in hardware mode.
- if ((instance->stop_mode == ME4600_AO_INF_STOP_MODE)
- && (circ_buffer_count <= ME4600_AO_FIFO_COUNT)) { //Change to hardware wraparound
- PDEBUG
- ("Changeing mode from software wraparound to hardware wraparound.\n");
- //Copy all data
- count =
- ao_write_data(instance, circ_buffer_count,
- instance->preloaded_count);
- ctrl &= ~ME4600_AO_CTRL_MODE_MASK;
- ctrl |= ME4600_AO_MODE_WRAPAROUND;
- }
-
- if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator.
- instance->preloaded_count = 0;
- } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend!
- PERROR_CRITICAL
- ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
- }
-
- //Set status to 'wait for start'
- instance->status = ao_status_stream_run_wait;
-
- status = inl(instance->status_reg);
- //Start state machine and interrupts
- ctrl &= ~(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
- if (instance->start_mode == ME4600_AO_EXT_TRIG) { // External trigger.
- PINFO("External trigger.\n");
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
- }
- if (!(status & ME4600_AO_STATUS_BIT_HF)) { //More than half!
- 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
- ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- }
- }
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- //Trigger output
- if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs
- spin_lock(instance->preload_reg_lock);
- synch = inl(instance->preload_reg);
- //Add channel to start list
- outl(synch | (ME4600_AO_SYNC_HOLD << instance->ao_idx),
- instance->preload_reg);
- 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));
-
- //Fire
- PINFO
- ("Fired all software synchronous outputs by software trigger.\n");
- outl(0x8000, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base, 0x8000);
-
- //Restore save settings
- outl(synch, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base, synch);
- spin_unlock(instance->preload_reg_lock);
- } else if (!instance->start_mode) { //Trigger outputs
-/*
- //Remove channel from start list. // <== Unnecessary. Removed.
- spin_lock(instance->preload_reg_lock);
- synch = inl(instance->preload_reg);
- outl(synch & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
- 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));
-*/
- //Fire
- PINFO("Software trigger.\n");
- outl(0x8000, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base, 0x8000);
-
-/*
- //Restore save settings. // <== Unnecessary. Removed.
- outl(synch, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch);
- spin_unlock(instance->preload_reg_lock);
-*/
- }
- // Set control task's timeout
- ref = jiffies;
- instance->timeout.delay = delay;
- instance->timeout.start_time = ref;
-
- if (status & ME4600_AO_STATUS_BIT_HF) { //Less than half but not empty!
- PINFO("Less than half.\n");
- if (instance->stop_data_count != 0) {
- count = ME4600_AO_FIFO_COUNT / 2;
- } else {
- count =
- ((ME4600_AO_FIFO_COUNT / 2) <
- instance->stop_data_count) ? ME4600_AO_FIFO_COUNT /
- 2 : instance->stop_data_count;
- }
-
- //Copy data
- count =
- ao_write_data(instance, count, instance->preloaded_count);
-
- if (count < 0) { //This should never happend!
- PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
-
- if (instance->mode == ME4600_AO_CONTINOUS) { //Continous
- instance->circ_buf.tail += count;
- instance->circ_buf.tail &= instance->circ_buf.mask;
- } else { //Wraparound
- instance->data_count += count;
- instance->preloaded_count += count;
-
- if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator.
- instance->preloaded_count = 0;
- } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend!
- PERROR_CRITICAL
- ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
- }
-
- status = inl(instance->status_reg);
- if (!(status & ME4600_AO_STATUS_BIT_HF)) { //More than half!
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- }
- }
- //Special case: Limited wraparound with less than HALF FIFO datas need work around to generate first interrupt.
- if ((instance->stop_mode != ME4600_AO_INF_STOP_MODE)
- && (instance->mode == ME4600_AO_SW_WRAP_MODE)
- && (circ_buffer_count <= (ME4600_AO_FIFO_COUNT / 2))) { //Put more data to FIFO
- PINFO("Limited wraparound with less than HALF FIFO datas.\n");
- if (instance->preloaded_count) { //This should never happend!
- PERROR_CRITICAL
- ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
-
- while (instance->stop_data_count > instance->data_count) { //Maximum data not set jet.
- //Copy to buffer
- if (circ_buffer_count != ao_write_data(instance, circ_buffer_count, 0)) { //This should never happend!
- PERROR_CRITICAL
- ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
- instance->data_count += circ_buffer_count;
-
- if (!((status = inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_HF)) { //FIFO is more than half. Enable IRQ and end copy.
- spin_lock_irqsave(&instance->subdevice_lock,
- cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg -
- instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- break;
- }
- }
- }
- // Schedule control task.
- instance->ao_control_task_flag = 1;
- queue_delayed_work(instance->me4600_workqueue,
- &instance->ao_control_task, 1);
-
- if (start_mode == ME_START_MODE_BLOCKING) { //Wait for start.
- //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
- wait_event_interruptible_timeout(instance->wait_queue,
- (instance->status !=
- ao_status_stream_run_wait),
- (delay) ? delay +
- 1 : LONG_MAX);
-
- if ((instance->status != ao_status_stream_run)
- && (instance->status != ao_status_stream_end)) {
- PDEBUG("Starting stream canceled. %d\n",
- instance->status);
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on start of state machine interrupted.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- } else if ((delay) && ((jiffies - ref) >= delay)) {
- if (instance->status != ao_status_stream_run) {
- if (instance->status == ao_status_stream_end) {
- PDEBUG("Timeout reached.\n");
- } else {
- if ((jiffies - ref) > delay) {
- PERROR
- ("Timeout reached. Not handled by control task!\n");
- } else {
- PERROR
- ("Timeout reached. Signal come but status is strange: %d\n",
- instance->status);
- }
- ao_stop_immediately(instance);
- }
-
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
- instance->status = ao_status_stream_end;
- err = ME_ERRNO_TIMEOUT;
- }
- }
- }
-
- ME_SUBDEVICE_EXIT;
- return err;
-}
-
-static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
- struct file *filep,
- int wait,
- int *status, int *values, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((wait != ME_WAIT_NONE) && (wait != ME_WAIT_IDLE)) {
- PERROR("Invalid wait argument specified.\n");
- *status = ME_STATUS_INVALID;
- return ME_ERRNO_INVALID_WAIT;
- }
-
- ME_SUBDEVICE_ENTER;
-
- switch (instance->status) {
- case ao_status_single_configured:
- case ao_status_single_end:
- case ao_status_stream_configured:
- case ao_status_stream_end:
- case ao_status_stream_fifo_error:
- case ao_status_stream_buffer_error:
- case ao_status_stream_error:
- *status = ME_STATUS_IDLE;
- break;
-
- case ao_status_single_run_wait:
- case ao_status_single_run:
- case ao_status_single_end_wait:
- case ao_status_stream_run_wait:
- case ao_status_stream_run:
- case ao_status_stream_end_wait:
- *status = ME_STATUS_BUSY;
- break;
-
- case ao_status_none:
- default:
- *status =
- (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ?
- ME_STATUS_BUSY : ME_STATUS_IDLE;
- break;
- }
-
- if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) {
- //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
- wait_event_interruptible_timeout(instance->wait_queue,
- ((instance->status !=
- ao_status_single_run_wait)
- && (instance->status !=
- ao_status_single_run)
- && (instance->status !=
- ao_status_single_end_wait)
- && (instance->status !=
- ao_status_stream_run_wait)
- && (instance->status !=
- ao_status_stream_run)
- && (instance->status !=
- ao_status_stream_end_wait)),
- LONG_MAX);
-
- if (instance->status != ao_status_stream_end) {
- PDEBUG("Wait for IDLE canceled. %d\n",
- instance->status);
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait for IDLE interrupted.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- }
-
- *status = ME_STATUS_IDLE;
- }
-
- *values = me_circ_buf_space(&instance->circ_buf);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
- struct file *filep,
- int stop_mode, int flags)
-{ // Stop work and empty buffer and FIFO
- int err = ME_ERRNO_SUCCESS;
- me4600_ao_subdevice_t *instance;
- unsigned long cpu_flags;
- volatile uint32_t ctrl;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags & ~ME_IO_STREAM_STOP_PRESERVE_BUFFERS) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((stop_mode != ME_STOP_MODE_IMMEDIATE)
- && (stop_mode != ME_STOP_MODE_LAST_VALUE)) {
- PERROR("Invalid stop mode specified.\n");
- return ME_ERRNO_INVALID_STOP_MODE;
- }
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (instance->status < ao_status_stream_configured) {
- //There is nothing to stop!
- PERROR("Subdevice not in streaming mode. %d\n",
- instance->status);
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-
- ME_SUBDEVICE_ENTER;
-
- //Mark as stopping. => Software stop.
- instance->status = ao_status_stream_end_wait;
-
- if (stop_mode == ME_STOP_MODE_IMMEDIATE) { //Stopped now!
- err = ao_stop_immediately(instance);
- } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
- ctrl = inl(instance->ctrl_reg) & ME4600_AO_CTRL_MODE_MASK;
- if (ctrl == ME4600_AO_MODE_WRAPAROUND) { //Hardware wraparound => Hardware stop.
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_RESET_IRQ;
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- }
- //Only runing process will interrupt this call. Events are signaled when status change.
- wait_event_interruptible_timeout(instance->wait_queue,
- (instance->status !=
- ao_status_stream_end_wait),
- LONG_MAX);
-
- if (instance->status != ao_status_stream_end) {
- PDEBUG("Stopping stream canceled.\n");
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Stopping stream interrupted.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- }
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
- ME4600_AO_CTRL_BIT_RESET_IRQ;
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- if (!flags) { //Reset FIFO
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO;
- }
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- if (!flags) { //Reset software buffer
- instance->circ_buf.head = 0;
- instance->circ_buf.tail = 0;
- instance->preloaded_count = 0;
- instance->data_count = 0;
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
- struct file *filep,
- int write_mode,
- int *values, int *count, int flags)
-{
- int err = ME_ERRNO_SUCCESS;
- me4600_ao_subdevice_t *instance;
- unsigned long cpu_flags = 0;
- uint32_t reg_copy;
-
- int copied_from_user = 0;
- int left_to_copy_from_user = *count;
-
- int copied_values;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- //Checking arguments
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (*count <= 0) {
- PERROR("Invalid count of values specified.\n");
- return ME_ERRNO_INVALID_VALUE_COUNT;
- }
-
- if (values == NULL) {
- PERROR("Invalid address of values specified.\n");
- return ME_ERRNO_INVALID_POINTER;
- }
-
- if ((instance->status == ao_status_none) || (instance->status == ao_status_single_configured)) { //The device is in single mode.
- PERROR
- ("Subdevice must be preinitialize correctly for streaming.\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-/// @note If no 'pre-load' is used. stream_start() will move data to FIFO.
- switch (write_mode) {
- case ME_WRITE_MODE_PRELOAD:
-
- //Device must be stopped.
- if ((instance->status != ao_status_stream_configured)
- && (instance->status != ao_status_stream_end)) {
- PERROR
- ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
- break;
- case ME_WRITE_MODE_NONBLOCKING:
- case ME_WRITE_MODE_BLOCKING:
- /// @note In blocking mode: When device is not runing and there is not enought space call will blocked up!
- /// @note Some other thread must empty buffer by starting engine.
- break;
-
- default:
- PERROR("Invalid write mode specified.\n");
- return ME_ERRNO_INVALID_WRITE_MODE;
- }
-
- if (instance->mode & ME4600_AO_WRAP_MODE) { //Wraparound mode. Device must be stopped.
- if ((instance->status != ao_status_stream_configured)
- && (instance->status != ao_status_stream_end)) {
- PERROR
- ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
- return ME_ERRNO_INVALID_WRITE_MODE;
- }
- }
-
- if ((instance->mode == ME4600_AO_HW_WRAP_MODE) && (write_mode != ME_WRITE_MODE_PRELOAD)) { // hardware wrap_around mode.
- //This is transparent for user.
- PDEBUG("Changing write_mode to ME_WRITE_MODE_PRELOAD.\n");
- write_mode = ME_WRITE_MODE_PRELOAD;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (write_mode == ME_WRITE_MODE_PRELOAD) { //Init enviroment - preload
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- reg_copy = inl(instance->ctrl_reg);
- //Check FIFO
- if (!(reg_copy & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO not active. Enable it.
- reg_copy |= ME4600_AO_CTRL_BIT_ENABLE_FIFO;
- outl(reg_copy, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- reg_copy);
- instance->preloaded_count = 0;
- }
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- }
-
- while (1) {
- //Copy to buffer. This step is common for all modes.
- copied_from_user =
- ao_get_data_from_user(instance, left_to_copy_from_user,
- values + (*count -
- left_to_copy_from_user));
- left_to_copy_from_user -= copied_from_user;
-
- reg_copy = inl(instance->status_reg);
- 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.
- PERROR("Broken pipe in write.\n");
- err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
- break;
- }
-
- 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!
-
- // Block interrupts.
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- reg_copy = inl(instance->ctrl_reg);
- //reg_copy &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- reg_copy |= ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(reg_copy, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- reg_copy);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- //Fast copy
- copied_values =
- ao_write_data(instance, ME4600_AO_FIFO_COUNT / 2,
- 0);
- if (copied_values > 0) {
- instance->circ_buf.tail += copied_values;
- instance->circ_buf.tail &=
- instance->circ_buf.mask;
- continue;
- }
- // Activate interrupts.
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- reg_copy = inl(instance->ctrl_reg);
- //reg_copy |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- reg_copy &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(reg_copy, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- reg_copy);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- if (copied_values == 0) { //This was checked and never should happend!
- PERROR_CRITICAL("COPING FINISH WITH 0!\n");
- }
-
- if (copied_values < 0) { //This was checked and never should happend!
- PERROR_CRITICAL
- ("COPING FINISH WITH AN ERROR!\n");
- instance->status = ao_status_stream_fifo_error;
- err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
- break;
- }
- }
-
- if (!left_to_copy_from_user) { //All datas were copied.
- break;
- } else { //Not all datas were copied.
- if (instance->mode & ME4600_AO_WRAP_MODE) { //Error too much datas! Wraparound is limited in size!
- PERROR
- ("Too much data for wraparound mode! Exceeded size of %ld.\n",
- ME4600_AO_CIRC_BUF_COUNT - 1);
- err = ME_ERRNO_RING_BUFFER_OVERFLOW;
- break;
- }
-
- if (write_mode != ME_WRITE_MODE_BLOCKING) { //Non blocking calls
- break;
- }
-
- wait_event_interruptible(instance->wait_queue,
- me_circ_buf_space(&instance->
- circ_buf));
-
- if (signal_pending(current)) {
- PERROR("Writing interrupted by signal.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- break;
- }
-
- if (instance->status == ao_status_none) { //Reset
- PERROR("Writing interrupted by reset.\n");
- err = ME_ERRNO_CANCELLED;
- break;
- }
- }
- }
-
- if (write_mode == ME_WRITE_MODE_PRELOAD) { //Copy data to FIFO - preload
- copied_values =
- ao_write_data_pooling(instance, ME4600_AO_FIFO_COUNT,
- instance->preloaded_count);
- instance->preloaded_count += copied_values;
- instance->data_count += copied_values;
-
- if ((instance->mode == ME4600_AO_HW_WRAP_MODE)
- && (me_circ_buf_values(&instance->circ_buf) >
- ME4600_AO_FIFO_COUNT)) {
- PERROR
- ("Too much data for hardware wraparound mode! Exceeded size of %d.\n",
- ME4600_AO_FIFO_COUNT);
- err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
- }
- }
-
- *count = *count - left_to_copy_from_user;
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
-{
- me4600_ao_subdevice_t *instance = dev_id;
- uint32_t irq_status;
- uint32_t ctrl;
- uint32_t status;
- int count = 0;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (irq != instance->irq) {
- PERROR("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- irq_status = inl(instance->irq_status_reg);
- if (!(irq_status & (ME4600_IRQ_STATUS_BIT_AO_HF << instance->ao_idx))) {
- PINFO("%ld Shared interrupt. %s(): ID=%d: status_reg=0x%04X\n",
- jiffies, __func__, instance->ao_idx, irq_status);
- return IRQ_NONE;
- }
-
- if (!instance->circ_buf.buf) {
- instance->status = ao_status_stream_error;
- PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n");
- //Block interrupts. Stop machine.
- ctrl = inl(instance->ctrl_reg);
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- ctrl |=
- ME4600_AO_CTRL_BIT_RESET_IRQ |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- //Inform user
- wake_up_interruptible_all(&instance->wait_queue);
- return IRQ_HANDLED;
- }
-
- status = inl(instance->status_reg);
- if (!(status & ME4600_AO_STATUS_BIT_FSM)) { //Too late. Not working! END? BROKEN PIPE?
- PDEBUG("Interrupt come but ISM is not working!\n");
- //Block interrupts. Stop machine.
- ctrl = inl(instance->ctrl_reg);
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- ctrl |=
- ME4600_AO_CTRL_BIT_RESET_IRQ | ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- return IRQ_HANDLED;
- }
- //General procedure. Process more datas.
-
-#ifdef MEDEBUG_DEBUG
- if (!me_circ_buf_values(&instance->circ_buf)) { //Buffer is empty!
- PDEBUG("Circular buffer empty!\n");
- }
-#endif
-
- //Check FIFO
- if (status & ME4600_AO_STATUS_BIT_HF) { //OK less than half
-
- //Block interrupts
- ctrl = inl(instance->ctrl_reg);
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- do {
- //Calculate how many should be copied.
- count =
- (instance->stop_data_count) ? instance->
- stop_data_count -
- instance->data_count : ME4600_AO_FIFO_COUNT / 2;
- if (ME4600_AO_FIFO_COUNT / 2 < count) {
- count = ME4600_AO_FIFO_COUNT / 2;
- }
- //Copy data
- if (instance->mode == ME4600_AO_CONTINOUS) { //Continous
- count = ao_write_data(instance, count, 0);
- if (count > 0) {
- instance->circ_buf.tail += count;
- instance->circ_buf.tail &=
- instance->circ_buf.mask;
- instance->data_count += count;
-
- if ((instance->status == ao_status_stream_end_wait) && !me_circ_buf_values(&instance->circ_buf)) { //Stoping. Whole buffer was copied.
- break;
- }
- }
- } else if ((instance->mode == ME4600_AO_SW_WRAP_MODE) && ((ctrl & ME4600_AO_CTRL_MODE_MASK) == ME4600_AO_MODE_CONTINUOUS)) { //Wraparound (software)
- if (instance->status == ao_status_stream_end_wait) { //We stoping => Copy to the end of the buffer.
- count =
- ao_write_data(instance, count, 0);
- } else { //Copy in wraparound mode.
- count =
- ao_write_data_wraparound(instance,
- count,
- instance->
- preloaded_count);
- }
-
- if (count > 0) {
- instance->data_count += count;
- instance->preloaded_count += count;
- instance->preloaded_count %=
- me_circ_buf_values(&instance->
- circ_buf);
-
- if ((instance->status == ao_status_stream_end_wait) && !instance->preloaded_count) { //Stoping. Whole buffer was copied.
- break;
- }
- }
- }
-
- if ((count <= 0) || (instance->stop_data_count && (instance->stop_data_count <= instance->data_count))) { //End of work.
- break;
- }
- } //Repeat if still is under half fifo
- while ((status =
- inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_HF);
-
- //Unblock interrupts
- ctrl = inl(instance->ctrl_reg);
- if (count >= 0) { //Copy was successful.
- if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. No more interrupts.
- PDEBUG("Finishing work. Interrupt disabled.\n");
- instance->status = ao_status_stream_end_wait;
- } else if (count > 0) { //Normal work. Enable interrupt.
- PDEBUG("Normal work. Enable interrupt.\n");
- ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- } else { //Normal work but there are no more data in buffer. Interrupt active but blocked. stream_write() will unblock it.
- PDEBUG
- ("No data in software buffer. Interrupt blocked.\n");
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- }
- } else { //Error during copy.
- instance->status = ao_status_stream_fifo_error;
- }
-
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- } else { //?? more than half
- PDEBUG
- ("Interrupt come but FIFO more than half full! Reset interrupt.\n");
- //Reset pending interrupt
- ctrl = inl(instance->ctrl_reg);
- ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- }
-
- PINFO("ISR: Buffer count: %d.(T:%d H:%d)\n",
- me_circ_buf_values(&instance->circ_buf), instance->circ_buf.tail,
- instance->circ_buf.head);
- PINFO("ISR: Stop count: %d.\n", instance->stop_count);
- PINFO("ISR: Stop data count: %d.\n", instance->stop_data_count);
- PINFO("ISR: Data count: %d.\n", instance->data_count);
-
- //Inform user
- wake_up_interruptible_all(&instance->wait_queue);
-
- return IRQ_HANDLED;
-}
-
-static void me4600_ao_destructor(struct me_subdevice *subdevice)
-{
- me4600_ao_subdevice_t *instance;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- instance->ao_control_task_flag = 0;
-
- // Reset subdevice to asure clean exit.
- me4600_ao_io_reset_subdevice(subdevice, NULL,
- ME_IO_RESET_SUBDEVICE_NO_FLAGS);
-
- // Remove any tasks from work queue. This is paranoic because it was done allready in reset().
- if (!cancel_delayed_work(&instance->ao_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue.
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(2);
- }
-
- if (instance->fifo) {
- if (instance->irq) {
- free_irq(instance->irq, instance);
- instance->irq = 0;
- }
-
- if (instance->circ_buf.buf) {
- free_pages((unsigned long)instance->circ_buf.buf,
- ME4600_AO_CIRC_BUF_SIZE_ORDER);
- }
- instance->circ_buf.buf = NULL;
- }
-
- me_subdevice_deinit(&instance->base);
- kfree(instance);
-}
-
-me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
- spinlock_t *preload_reg_lock,
- uint32_t *preload_flags,
- int ao_idx,
- int fifo,
- int irq,
- struct workqueue_struct *me4600_wq)
-{
- me4600_ao_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed. idx=%d\n", ao_idx);
-
- // Allocate memory for subdevice instance.
- subdevice = kmalloc(sizeof(me4600_ao_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me4600_ao_subdevice_t));
-
- // Initialize subdevice base class.
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->preload_reg_lock = preload_reg_lock;
- subdevice->preload_flags = preload_flags;
-
- // Store analog output index.
- subdevice->ao_idx = ao_idx;
-
- // Store if analog output has fifo.
- subdevice->fifo = (ao_idx < fifo) ? 1 : 0;
-
- if (subdevice->fifo) { // Allocate and initialize circular buffer.
- subdevice->circ_buf.mask = ME4600_AO_CIRC_BUF_COUNT - 1;
-
- subdevice->circ_buf.buf =
- (void *)__get_free_pages(GFP_KERNEL,
- ME4600_AO_CIRC_BUF_SIZE_ORDER);
- PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf,
- ME4600_AO_CIRC_BUF_SIZE);
-
- if (!subdevice->circ_buf.buf) {
- PERROR
- ("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
-
- memset(subdevice->circ_buf.buf, 0, ME4600_AO_CIRC_BUF_SIZE);
- } else { // No FIFO.
- subdevice->circ_buf.mask = 0;
- subdevice->circ_buf.buf = NULL;
- }
-
- subdevice->circ_buf.head = 0;
- subdevice->circ_buf.tail = 0;
-
- subdevice->status = ao_status_none;
- subdevice->ao_control_task_flag = 0;
- subdevice->timeout.delay = 0;
- subdevice->timeout.start_time = jiffies;
-
- // Initialize wait queue.
- init_waitqueue_head(&subdevice->wait_queue);
-
- // Initialize single value to 0V.
- subdevice->single_value = 0x8000;
- subdevice->single_value_in_fifo = 0x8000;
-
- // Register interrupt service routine.
- if (subdevice->fifo) {
- subdevice->irq = irq;
- if (request_irq(subdevice->irq, me4600_ao_isr,
- IRQF_DISABLED | IRQF_SHARED,
- ME4600_NAME, subdevice)) {
- PERROR("Cannot get interrupt line.\n");
- PDEBUG("free circ_buf = %p size=%d",
- subdevice->circ_buf.buf,
- PAGE_SHIFT << ME4600_AO_CIRC_BUF_SIZE_ORDER);
- free_pages((unsigned long)subdevice->circ_buf.buf,
- ME4600_AO_CIRC_BUF_SIZE_ORDER);
- me_subdevice_deinit((me_subdevice_t *) subdevice);
- kfree(subdevice);
- return NULL;
- }
- PINFO("Registered irq=%d.\n", subdevice->irq);
- } else {
- subdevice->irq = 0;
- }
-
- // Initialize registers.
- subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
- subdevice->preload_reg = reg_base + ME4600_AO_SYNC_REG;
- if (ao_idx == 0) {
- subdevice->ctrl_reg = reg_base + ME4600_AO_00_CTRL_REG;
- subdevice->status_reg = reg_base + ME4600_AO_00_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME4600_AO_00_FIFO_REG;
- subdevice->single_reg = reg_base + ME4600_AO_00_SINGLE_REG;
- subdevice->timer_reg = reg_base + ME4600_AO_00_TIMER_REG;
- subdevice->reg_base = reg_base;
- subdevice->bitpattern = 0;
- } else if (ao_idx == 1) {
- subdevice->ctrl_reg = reg_base + ME4600_AO_01_CTRL_REG;
- subdevice->status_reg = reg_base + ME4600_AO_01_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME4600_AO_01_FIFO_REG;
- subdevice->single_reg = reg_base + ME4600_AO_01_SINGLE_REG;
- subdevice->timer_reg = reg_base + ME4600_AO_01_TIMER_REG;
- subdevice->reg_base = reg_base;
- subdevice->bitpattern = 0;
- } else if (ao_idx == 2) {
- subdevice->ctrl_reg = reg_base + ME4600_AO_02_CTRL_REG;
- subdevice->status_reg = reg_base + ME4600_AO_02_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME4600_AO_02_FIFO_REG;
- subdevice->single_reg = reg_base + ME4600_AO_02_SINGLE_REG;
- subdevice->timer_reg = reg_base + ME4600_AO_02_TIMER_REG;
- subdevice->reg_base = reg_base;
- subdevice->bitpattern = 0;
- } else if (ao_idx == 3) {
- subdevice->ctrl_reg = reg_base + ME4600_AO_03_CTRL_REG;
- subdevice->status_reg = reg_base + ME4600_AO_03_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME4600_AO_03_FIFO_REG;
- subdevice->single_reg = reg_base + ME4600_AO_03_SINGLE_REG;
- subdevice->timer_reg = reg_base + ME4600_AO_03_TIMER_REG;
- subdevice->reg_base = reg_base;
- subdevice->bitpattern = 1;
- } else {
- PERROR_CRITICAL("WRONG SUBDEVICE idx=%d!", ao_idx);
- me_subdevice_deinit((me_subdevice_t *) subdevice);
- if (subdevice->fifo) {
- free_pages((unsigned long)subdevice->circ_buf.buf,
- ME4600_AO_CIRC_BUF_SIZE_ORDER);
- }
- subdevice->circ_buf.buf = NULL;
- kfree(subdevice);
- return NULL;
- }
-
- // Override base class methods.
- subdevice->base.me_subdevice_destructor = me4600_ao_destructor;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me4600_ao_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me4600_ao_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me4600_ao_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me4600_ao_io_single_write;
- subdevice->base.me_subdevice_io_stream_config =
- me4600_ao_io_stream_config;
- subdevice->base.me_subdevice_io_stream_new_values =
- me4600_ao_io_stream_new_values;
- subdevice->base.me_subdevice_io_stream_write =
- me4600_ao_io_stream_write;
- subdevice->base.me_subdevice_io_stream_start =
- me4600_ao_io_stream_start;
- subdevice->base.me_subdevice_io_stream_status =
- me4600_ao_io_stream_status;
- subdevice->base.me_subdevice_io_stream_stop = me4600_ao_io_stream_stop;
- subdevice->base.me_subdevice_query_number_channels =
- me4600_ao_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me4600_ao_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me4600_ao_query_subdevice_caps;
- subdevice->base.me_subdevice_query_subdevice_caps_args =
- me4600_ao_query_subdevice_caps_args;
- subdevice->base.me_subdevice_query_range_by_min_max =
- me4600_ao_query_range_by_min_max;
- subdevice->base.me_subdevice_query_number_ranges =
- me4600_ao_query_number_ranges;
- subdevice->base.me_subdevice_query_range_info =
- me4600_ao_query_range_info;
- subdevice->base.me_subdevice_query_timer = me4600_ao_query_timer;
-
- // Prepare work queue
- subdevice->me4600_workqueue = me4600_wq;
-
-/* workqueue API changed in kernel 2.6.20 */
- INIT_DELAYED_WORK(&subdevice->ao_control_task,
- me4600_ao_work_control_task);
-
- if (subdevice->fifo) { // Set speed for single operations.
- outl(ME4600_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
- subdevice->hardware_stop_delay = HZ / 10; //100ms
- }
-
- return subdevice;
-}
-
-/** @brief Stop presentation. Preserve FIFOs.
-*
-* @param instance The subdevice instance (pointer).
-*/
-inline int ao_stop_immediately(me4600_ao_subdevice_t *instance)
-{
- unsigned long cpu_flags;
- uint32_t ctrl;
- int timeout;
- int i;
-
- timeout =
- (instance->hardware_stop_delay >
- (HZ / 10)) ? instance->hardware_stop_delay : HZ / 10;
- for (i = 0; i <= timeout; i++) {
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
- | ME4600_AO_CTRL_BIT_RESET_IRQ;
- ctrl &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
- ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) { // Exit.
- break;
- }
- //Still working!
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
-
- if (i > timeout) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- return ME_ERRNO_INTERNAL;
- }
- return ME_ERRNO_SUCCESS;
-}
-
-/** @brief Copy data from circular buffer to fifo (fast) in wraparound.
-* @note This is time critical function. Checking is done at begining and end only.
-* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied data.
-* @return On error/success: 0. No datas were copied => no data in buffer.
-* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
-*/
-inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count,
- int start_pos)
-{ /// @note This is time critical function!
- uint32_t status;
- uint32_t value;
- int pos =
- (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
- int local_count = count;
- int i = 1;
-
- if (count <= 0) { //Wrong count!
- return 0;
- }
-
- while (i < local_count) {
- //Get value from buffer
- value = *(instance->circ_buf.buf + pos);
- //Prepare it
- if (instance->ao_idx & 0x1) {
- value <<= 16;
- }
- //Put value to FIFO
- outl(value, instance->fifo_reg);
- //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);
-
- pos++;
- pos &= instance->circ_buf.mask;
- if (pos == instance->circ_buf.head) {
- pos = instance->circ_buf.tail;
- }
- i++;
- }
-
- status = inl(instance->status_reg);
- if (!(status & ME4600_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied!
- PERROR("FIFO was full before all datas were copied! idx=%d\n",
- instance->ao_idx);
- return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
- } else { //Add last value
- value = *(instance->circ_buf.buf + pos);
- if (instance->ao_idx & 0x1) {
- value <<= 16;
- }
- //Put value to FIFO
- outl(value, instance->fifo_reg);
- //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);
- }
-
- PINFO("WRAPAROUND LOADED %d values. idx=%d\n", local_count,
- instance->ao_idx);
- return local_count;
-}
-
-/** @brief Copy data from software buffer to fifo (fast).
-* @note This is time critical function. Checking is done at begining and end only.
-* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied data.
-* @return On error/success: 0. No datas were copied => no data in buffer.
-* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
-*/
-inline int ao_write_data(me4600_ao_subdevice_t *instance, int count,
- int start_pos)
-{ /// @note This is time critical function!
- uint32_t status;
- uint32_t value;
- int pos =
- (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
- int local_count = count;
- int max_count;
- int i = 1;
-
- if (count <= 0) { //Wrong count!
- return 0;
- }
-
- max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
- if (max_count <= 0) { //No data to copy!
- return 0;
- }
-
- if (max_count < count) {
- local_count = max_count;
- }
-
- while (i < local_count) {
- //Get value from buffer
- value = *(instance->circ_buf.buf + pos);
- //Prepare it
- if (instance->ao_idx & 0x1) {
- value <<= 16;
- }
- //Put value to FIFO
- outl(value, instance->fifo_reg);
- //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);
-
- pos++;
- pos &= instance->circ_buf.mask;
- i++;
- }
-
- status = inl(instance->status_reg);
- if (!(status & ME4600_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied!
- PERROR("FIFO was full before all datas were copied! idx=%d\n",
- instance->ao_idx);
- return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
- } else { //Add last value
- value = *(instance->circ_buf.buf + pos);
- if (instance->ao_idx & 0x1) {
- value <<= 16;
- }
- //Put value to FIFO
- outl(value, instance->fifo_reg);
- //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);
- }
-
- PINFO("FAST LOADED %d values. idx=%d\n", local_count, instance->ao_idx);
- return local_count;
-}
-
-/** @brief Copy data from software buffer to fifo (slow).
-* @note This is slow function that copy all data from buffer to FIFO with full control.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied values.
-* @return On error/success: 0. FIFO was full at begining.
-* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
-*/
-inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count,
- int start_pos)
-{ /// @note This is slow function!
- uint32_t status;
- uint32_t value;
- int pos =
- (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
- int local_count = count;
- int i;
- int max_count;
-
- if (count <= 0) { //Wrong count!
- PERROR("SLOW LOADED: Wrong count! idx=%d\n", instance->ao_idx);
- return 0;
- }
-
- max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
- if (max_count <= 0) { //No data to copy!
- PERROR("SLOW LOADED: No data to copy! idx=%d\n",
- instance->ao_idx);
- return 0;
- }
-
- if (max_count < count) {
- local_count = max_count;
- }
-
- for (i = 0; i < local_count; i++) {
- status = inl(instance->status_reg);
- if (!(status & ME4600_AO_STATUS_BIT_FF)) { //FIFO is full!
- return i;
- }
- //Get value from buffer
- value = *(instance->circ_buf.buf + pos);
- //Prepare it
- if (instance->ao_idx & 0x1) {
- value <<= 16;
- }
- //Put value to FIFO
- outl(value, instance->fifo_reg);
- //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);
-
- pos++;
- pos &= instance->circ_buf.mask;
- }
-
- PINFO("SLOW LOADED %d values. idx=%d\n", local_count, instance->ao_idx);
- return local_count;
-}
-
-/** @brief Copy data from user space to circular buffer.
-* @param instance The subdevice instance (pointer).
-* @param count Number of datas in user space.
-* @param user_values Buffer's pointer.
-*
-* @return On success: Number of copied values.
-* @return On error: -ME_ERRNO_INTERNAL.
-*/
-inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count,
- int *user_values)
-{
- int i, err;
- int empty_space;
- int copied;
- int value;
-
- empty_space = me_circ_buf_space(&instance->circ_buf);
- //We have only this space free.
- copied = (count < empty_space) ? count : empty_space;
- for (i = 0; i < copied; i++) { //Copy from user to buffer
- if ((err = get_user(value, (int *)(user_values + i)))) {
- PERROR
- ("BUFFER LOADED: get_user(0x%p) return an error: %d. idx=%d\n",
- user_values + i, err, instance->ao_idx);
- return -ME_ERRNO_INTERNAL;
- }
- /// @note The analog output in me4600 series has size of 16 bits.
- *(instance->circ_buf.buf + instance->circ_buf.head) =
- (uint16_t) value;
- instance->circ_buf.head++;
- instance->circ_buf.head &= instance->circ_buf.mask;
- }
-
- PINFO("BUFFER LOADED %d values. idx=%d\n", copied, instance->ao_idx);
- return copied;
-}
-
-/** @brief Checking actual hardware and logical state.
-* @param instance The subdevice instance (pointer).
-*/
-static void me4600_ao_work_control_task(struct work_struct *work)
-{
- me4600_ao_subdevice_t *instance;
- unsigned long cpu_flags = 0;
- uint32_t status;
- uint32_t ctrl;
- uint32_t synch;
- int reschedule = 0;
- int signaling = 0;
-
- instance =
- container_of((void *)work, me4600_ao_subdevice_t, ao_control_task);
- PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
- instance->ao_idx);
-
- status = inl(instance->status_reg);
- PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->status_reg - instance->reg_base, status);
-
- switch (instance->status) { // Checking actual mode.
-
- // Not configured for work.
- case ao_status_none:
- break;
-
- //This are stable modes. No need to do anything. (?)
- case ao_status_single_configured:
- case ao_status_stream_configured:
- case ao_status_stream_fifo_error:
- case ao_status_stream_buffer_error:
- case ao_status_stream_error:
- PERROR("Shouldn't be running!.\n");
- break;
-
- case ao_status_stream_end:
- if (!instance->fifo) {
- PERROR_CRITICAL
- ("Streaming on single device! This feature is not implemented in this version!\n");
- instance->status = ao_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
- }
- case ao_status_single_end:
- if (status & ME4600_AO_STATUS_BIT_FSM) { // State machine is working but the status is set to end. Force stop.
-
- // Wait for stop.
- reschedule = 1;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP
- | ME4600_AO_CTRL_BIT_RESET_IRQ;
- ctrl &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
- ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
- ctrl &=
- ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- break;
-
- // Single modes
- case ao_status_single_run_wait:
- case ao_status_single_run:
- case ao_status_single_end_wait:
-
- if (!(status & ME4600_AO_STATUS_BIT_FSM)) { // State machine is not working.
- if (((instance->fifo)
- && (!(status & ME4600_AO_STATUS_BIT_EF)))
- || (!(instance->fifo))) { // Single is in end state.
- PDEBUG("Single call has been complited.\n");
-
- // Set correct value for single_read();
- instance->single_value =
- instance->single_value_in_fifo;
-
- // Set status as 'ao_status_single_end'
- instance->status = ao_status_single_end;
-
- // Signal the end.
- signaling = 1;
- // Wait for stop ISM.
- reschedule = 1;
-
- break;
- }
- }
- // Check timeout.
- if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
- PDEBUG("Timeout reached.\n");
- // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
- ME4600_AO_CTRL_BIT_RESET_IRQ;
- ctrl &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
- ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
- /// Fix for timeout error.
- ctrl &=
- ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
- if (instance->fifo) { //Disabling FIFO
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO;
- }
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- spin_lock(instance->preload_reg_lock);
- //Remove from synchronous start. Block triggering from this output.
- synch = inl(instance->preload_reg);
- synch &=
- ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) <<
- instance->ao_idx);
- if (!(instance->fifo)) { // No FIFO - set to single safe mode
- synch |=
- ME4600_AO_SYNC_HOLD << instance->ao_idx;
- }
- outl(synch, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- synch);
- spin_unlock(instance->preload_reg_lock);
-
- if (!(instance->fifo)) { // No FIFO
- // Restore old settings.
- PDEBUG("Write old value back to register.\n");
- outl(instance->single_value,
- instance->single_reg);
- PDEBUG_REG
- ("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base,
- instance->single_value);
- }
- // Set correct value for single_read();
- instance->single_value_in_fifo = instance->single_value;
-
- instance->status = ao_status_single_end;
-
- // Signal the end.
- signaling = 1;
- }
- // Wait for stop.
- reschedule = 1;
- break;
-
- // Stream modes
- case ao_status_stream_run_wait:
- if (!instance->fifo) {
- PERROR_CRITICAL
- ("Streaming on single device! This feature is not implemented in this version!\n");
- instance->status = ao_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
- }
-
- if (status & ME4600_AO_STATUS_BIT_FSM) { // State machine is working. Waiting for start finish.
- instance->status = ao_status_stream_run;
-
- // Signal end of this step
- signaling = 1;
- } else { // State machine is not working.
- if (!(status & ME4600_AO_STATUS_BIT_EF)) { // FIFO is empty. Procedure has started and finish already!
- instance->status = ao_status_stream_end;
-
- // Signal the end.
- signaling = 1;
- // Wait for stop.
- reschedule = 1;
- break;
- }
- }
-
- // Check timeout.
- if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
- PDEBUG("Timeout reached.\n");
- // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
- ME4600_AO_CTRL_BIT_RESET_IRQ;
- ctrl &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
- ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- spin_lock(instance->preload_reg_lock);
- //Remove from synchronous start. Block triggering from this output.
- synch = inl(instance->preload_reg);
- synch &=
- ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) <<
- instance->ao_idx);
- outl(synch, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- synch);
- spin_unlock(instance->preload_reg_lock);
-
- instance->status = ao_status_stream_end;
-
- // Signal the end.
- signaling = 1;
- }
- // Wait for stop.
- reschedule = 1;
- break;
-
- case ao_status_stream_run:
- if (!instance->fifo) {
- PERROR_CRITICAL
- ("Streaming on single device! This feature is not implemented in this version!\n");
- instance->status = ao_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
- }
-
- if (!(status & ME4600_AO_STATUS_BIT_FSM)) { // State machine is not working. This is an error.
- // BROKEN PIPE!
- if (!(status & ME4600_AO_STATUS_BIT_EF)) { // FIFO is empty.
- if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty.
- if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. Requed data shown.
- PDEBUG
- ("ISM stoped. No data in FIFO. Buffer is not empty.\n");
- instance->status =
- ao_status_stream_end;
- } else {
- PERROR
- ("Output stream has been broken. ISM stoped. No data in FIFO. Buffer is not empty.\n");
- instance->status =
- ao_status_stream_buffer_error;
- }
- } else { // Software buffer is empty.
- PDEBUG
- ("ISM stoped. No data in FIFO. Buffer is empty.\n");
- instance->status = ao_status_stream_end;
- }
- } else { // There are still datas in FIFO.
- if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty.
- PERROR
- ("Output stream has been broken. ISM stoped but some data in FIFO and buffer.\n");
- } else { // Software buffer is empty.
- PERROR
- ("Output stream has been broken. ISM stoped but some data in FIFO. Buffer is empty.\n");
- }
- instance->status = ao_status_stream_fifo_error;
-
- }
-
- // Signal the failure.
- signaling = 1;
- break;
- }
- // Wait for stop.
- reschedule = 1;
- break;
-
- case ao_status_stream_end_wait:
- if (!instance->fifo) {
- PERROR_CRITICAL
- ("Streaming on single device! This feature is not implemented in this version!\n");
- instance->status = ao_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
- }
-
- if (!(status & ME4600_AO_STATUS_BIT_FSM)) { // State machine is not working. Waiting for stop finish.
- instance->status = ao_status_stream_end;
- signaling = 1;
- }
- // State machine is working.
- reschedule = 1;
- break;
-
- default:
- PERROR_CRITICAL("Status is in wrong state (%d)!\n",
- instance->status);
- instance->status = ao_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
-
- }
-
- if (signaling) { //Signal it.
- wake_up_interruptible_all(&instance->wait_queue);
- }
-
- if (instance->ao_control_task_flag && reschedule) { // Reschedule task
- queue_delayed_work(instance->me4600_workqueue,
- &instance->ao_control_task, 1);
- } else {
- PINFO("<%s> Ending control task.\n", __func__);
- }
-
-}
-#else
-/// @note SPECIAL BUILD FOR BOSCH
-/// @author Guenter Gebhardt
-static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
- struct file *filep, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t tmp;
- unsigned long status;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER spin_lock_irqsave(&instance->subdevice_lock, status);
- spin_lock(instance->preload_reg_lock);
- tmp = inl(instance->preload_reg);
- tmp &= ~(0x10001 << instance->ao_idx);
- outl(tmp, instance->preload_reg);
- *instance->preload_flags &= ~(0x1 << instance->ao_idx);
- spin_unlock(instance->preload_reg_lock);
-
- tmp = inl(instance->ctrl_reg);
- tmp |= ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, instance->ctrl_reg);
-
- while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ;
-
- outl(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP,
- instance->ctrl_reg);
-
- outl(0x8000, instance->single_reg);
-
- instance->single_value = 0x8000;
- instance->circ_buf.head = 0;
- instance->circ_buf.tail = 0;
-
- spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t tmp;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
- if (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) {
- PERROR("Subdevice is busy.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- if (channel == 0) {
- if (single_config == 0) {
- if (ref == ME_REF_AO_GROUND) {
- if (trig_chan == ME_TRIG_CHAN_DEFAULT) {
- if (trig_type == ME_TRIG_TYPE_SW) {
- tmp = inl(instance->ctrl_reg);
- tmp |=
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, instance->ctrl_reg);
- tmp =
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, instance->ctrl_reg);
-
- spin_lock(instance->
- preload_reg_lock);
- tmp =
- inl(instance->preload_reg);
- tmp &=
- ~(0x10001 << instance->
- ao_idx);
- outl(tmp,
- instance->preload_reg);
- *instance->preload_flags &=
- ~(0x1 << instance->ao_idx);
- spin_unlock(instance->
- preload_reg_lock);
- } else if (trig_type ==
- ME_TRIG_TYPE_EXT_DIGITAL) {
- if (trig_edge ==
- ME_TRIG_EDGE_RISING) {
- tmp =
- inl(instance->
- ctrl_reg);
- tmp |=
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp,
- instance->
- ctrl_reg);
- tmp =
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
- |
- ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
- outl(tmp,
- instance->
- ctrl_reg);
- } else if (trig_edge ==
- ME_TRIG_EDGE_FALLING)
- {
- tmp =
- inl(instance->
- ctrl_reg);
- tmp |=
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp,
- instance->
- ctrl_reg);
- tmp =
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
- |
- ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG
- |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
- outl(tmp,
- instance->
- ctrl_reg);
- } else if (trig_edge ==
- ME_TRIG_EDGE_ANY) {
- tmp =
- inl(instance->
- ctrl_reg);
- tmp |=
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp,
- instance->
- ctrl_reg);
- tmp =
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
- |
- ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG
- |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE
- |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
- outl(tmp,
- instance->
- ctrl_reg);
- } else {
- PERROR
- ("Invalid trigger edge.\n");
- err =
- ME_ERRNO_INVALID_TRIG_EDGE;
- goto ERROR;
- }
-
- spin_lock(instance->
- preload_reg_lock);
-
- tmp =
- inl(instance->preload_reg);
- tmp &=
- ~(0x10001 << instance->
- ao_idx);
- tmp |= 0x1 << instance->ao_idx;
- outl(tmp,
- instance->preload_reg);
- *instance->preload_flags &=
- ~(0x1 << instance->ao_idx);
- spin_unlock(instance->
- preload_reg_lock);
- } else {
- PERROR
- ("Invalid trigger type.\n");
- err =
- ME_ERRNO_INVALID_TRIG_TYPE;
- goto ERROR;
- }
- } else if (trig_chan ==
- ME_TRIG_CHAN_SYNCHRONOUS) {
- if (trig_type == ME_TRIG_TYPE_SW) {
- tmp = inl(instance->ctrl_reg);
- tmp |=
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, instance->ctrl_reg);
- tmp =
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, instance->ctrl_reg);
-
- spin_lock(instance->
- preload_reg_lock);
- tmp =
- inl(instance->preload_reg);
- tmp &=
- ~(0x10001 << instance->
- ao_idx);
- tmp |= 0x1 << instance->ao_idx;
- outl(tmp,
- instance->preload_reg);
- *instance->preload_flags |=
- 0x1 << instance->ao_idx;
- spin_unlock(instance->
- preload_reg_lock);
- } else if (trig_type ==
- ME_TRIG_TYPE_EXT_DIGITAL) {
- if (trig_edge ==
- ME_TRIG_EDGE_RISING) {
- tmp =
- inl(instance->
- ctrl_reg);
- tmp |=
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp,
- instance->
- ctrl_reg);
- tmp =
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp,
- instance->
- ctrl_reg);
- } else if (trig_edge ==
- ME_TRIG_EDGE_FALLING)
- {
- tmp =
- inl(instance->
- ctrl_reg);
- tmp |=
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp,
- instance->
- ctrl_reg);
- tmp =
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
- |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
- outl(tmp,
- instance->
- ctrl_reg);
- } else if (trig_edge ==
- ME_TRIG_EDGE_ANY) {
- tmp =
- inl(instance->
- ctrl_reg);
- tmp |=
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp,
- instance->
- ctrl_reg);
- tmp =
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
- |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE
- |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
- outl(tmp,
- instance->
- ctrl_reg);
- } else {
- PERROR
- ("Invalid trigger edge.\n");
- err =
- ME_ERRNO_INVALID_TRIG_EDGE;
- goto ERROR;
- }
-
- spin_lock(instance->
- preload_reg_lock);
-
- tmp =
- inl(instance->preload_reg);
- tmp |=
- 0x10001 << instance->ao_idx;
- outl(tmp,
- instance->preload_reg);
- *instance->preload_flags &=
- ~(0x1 << instance->ao_idx);
- spin_unlock(instance->
- preload_reg_lock);
- } else {
- PERROR
- ("Invalid trigger type.\n");
- err =
- ME_ERRNO_INVALID_TRIG_TYPE;
- goto ERROR;
- }
- } else {
- PERROR
- ("Invalid trigger channel specified.\n");
- err = ME_ERRNO_INVALID_REF;
- goto ERROR;
- }
- } else {
- PERROR("Invalid analog reference specified.\n");
- err = ME_ERRNO_INVALID_REF;
- goto ERROR;
- }
- } else {
- PERROR("Invalid single config specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- goto ERROR;
- }
- } else {
- PERROR("Invalid channel number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- goto ERROR;
- }
-
-ERROR:
-
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long tmp;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- if (channel != 0) {
- PERROR("Invalid channel number specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- tmp = inl(instance->ctrl_reg);
-
- if (tmp & 0x3) {
- PERROR("Not in single mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- } else {
- *value = instance->single_value;
- }
-
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long mask = 0;
- unsigned long tmp;
- unsigned long cpu_flags;
- int i;
- wait_queue_head_t queue;
- unsigned long j;
- unsigned long delay = 0;
-
- PDEBUG("executed.\n");
-
- init_waitqueue_head(&queue);
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- if (channel != 0) {
- PERROR("Invalid channel number specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- delay = (time_out * HZ) / 1000;
-
- if (delay == 0)
- delay = 1;
- }
-
- ME_SUBDEVICE_ENTER
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
- tmp = inl(instance->ctrl_reg);
-
- if (tmp & 0x3) {
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- PERROR("Not in single mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- goto ERROR;
- }
-
- if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) {
- outl(value, instance->single_reg);
- instance->single_value = value;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
- j = jiffies;
-
- while (inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM) {
- interruptible_sleep_on_timeout(&queue, 1);
-
- if (signal_pending(current)) {
- PERROR
- ("Wait on external trigger interrupted by signal.\n");
- err = ME_ERRNO_SIGNAL;
- goto ERROR;
- }
-
- if (delay && ((jiffies - j) > delay)) {
- PERROR("Timeout reached.\n");
- err = ME_ERRNO_TIMEOUT;
- goto ERROR;
- }
- }
- }
- } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx))
- == (0x10001 << instance->ao_idx)) {
- if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {
- tmp |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
- outl(tmp, instance->ctrl_reg);
- outl(value, instance->single_reg);
- instance->single_value = value;
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
- j = jiffies;
-
- while (inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM) {
- interruptible_sleep_on_timeout(&queue,
- 1);
-
- if (signal_pending(current)) {
- PERROR
- ("Wait on external trigger interrupted by signal.\n");
- err = ME_ERRNO_SIGNAL;
- goto ERROR;
- }
-
- if (delay && ((jiffies - j) > delay)) {
- PERROR("Timeout reached.\n");
- err = ME_ERRNO_TIMEOUT;
- goto ERROR;
- }
- }
- }
- } else {
- outl(value, instance->single_reg);
- instance->single_value = value;
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- }
- } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx))
- == (0x1 << instance->ao_idx)) {
- outl(value, instance->single_reg);
- instance->single_value = value;
-
- PDEBUG("Synchronous SW, flags = 0x%X.\n", flags);
-
- if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {
- PDEBUG("Trigger synchronous SW.\n");
- spin_lock(instance->preload_reg_lock);
- tmp = inl(instance->preload_reg);
-
- for (i = 0; i < ME4600_AO_MAX_SUBDEVICES; i++) {
- if ((*instance->preload_flags & (0x1 << i))) {
- if ((tmp & (0x10001 << i)) ==
- (0x1 << i)) {
- mask |= 0x1 << i;
- }
- }
- }
-
- tmp &= ~(mask);
-
- outl(tmp, instance->preload_reg);
- spin_unlock(instance->preload_reg_lock);
- }
-
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- } else {
- outl(value, instance->single_reg);
- instance->single_value = value;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- }
-
-ERROR:
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
- struct file *filep,
- meIOStreamConfig_t *config_list,
- int count,
- meIOStreamTrigger_t *trigger,
- int fifo_irq_threshold, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long ctrl;
- unsigned long tmp;
- unsigned long cpu_flags;
- uint64_t conv_ticks;
- unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
- unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- conv_ticks =
- (uint64_t) conv_start_ticks_low +
- ((uint64_t) conv_start_ticks_high << 32);
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- ME_SUBDEVICE_ENTER
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
- if ((inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_FSM) {
- PERROR("Subdevice is busy.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- ctrl = inl(instance->ctrl_reg);
- ctrl |= ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(ctrl, instance->ctrl_reg);
- ctrl = ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(ctrl, instance->ctrl_reg);
-
- if (count != 1) {
- PERROR("Invalid stream configuration list count specified.\n");
- err = ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
- goto ERROR;
- }
-
- if (config_list[0].iChannel != 0) {
- PERROR("Invalid channel number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- goto ERROR;
- }
-
- if (config_list[0].iStreamConfig != 0) {
- PERROR("Invalid stream config specified.\n");
- err = ME_ERRNO_INVALID_STREAM_CONFIG;
- goto ERROR;
- }
-
- if (config_list[0].iRef != ME_REF_AO_GROUND) {
- PERROR("Invalid analog reference.\n");
- err = ME_ERRNO_INVALID_REF;
- goto ERROR;
- }
-
- if ((trigger->iAcqStartTicksLow != 0)
- || (trigger->iAcqStartTicksHigh != 0)) {
- PERROR
- ("Invalid acquisition start trigger argument specified.\n");
- err = ME_ERRNO_INVALID_ACQ_START_ARG;
- goto ERROR;
- }
-
- switch (trigger->iAcqStartTrigType) {
-
- case ME_TRIG_TYPE_SW:
- break;
-
- case ME_TRIG_TYPE_EXT_DIGITAL:
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
- switch (trigger->iAcqStartTrigEdge) {
-
- case ME_TRIG_EDGE_RISING:
- break;
-
- case ME_TRIG_EDGE_FALLING:
- ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
-
- break;
-
- case ME_TRIG_EDGE_ANY:
- ctrl |=
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
- ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-
- break;
-
- default:
- PERROR
- ("Invalid acquisition start trigger edge specified.\n");
-
- err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
-
- goto ERROR;
-
- break;
- }
-
- break;
-
- default:
- PERROR("Invalid acquisition start trigger type specified.\n");
-
- err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
-
- goto ERROR;
-
- break;
- }
-
- switch (trigger->iScanStartTrigType) {
-
- case ME_TRIG_TYPE_FOLLOW:
- break;
-
- default:
- PERROR("Invalid scan start trigger type specified.\n");
-
- err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
-
- goto ERROR;
-
- break;
- }
-
- switch (trigger->iConvStartTrigType) {
-
- case ME_TRIG_TYPE_TIMER:
- if ((conv_ticks < ME4600_AO_MIN_CHAN_TICKS)
- || (conv_ticks > ME4600_AO_MAX_CHAN_TICKS)) {
- PERROR
- ("Invalid conv start trigger argument specified.\n");
- err = ME_ERRNO_INVALID_CONV_START_ARG;
- goto ERROR;
- }
-
- break;
-
- default:
- PERROR("Invalid conv start trigger type specified.\n");
-
- err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
-
- goto ERROR;
-
- break;
- }
-
- /* Preset to hardware wraparound mode */
- instance->flags &= ~(ME4600_AO_FLAGS_SW_WRAP_MODE_MASK);
-
- switch (trigger->iScanStopTrigType) {
-
- case ME_TRIG_TYPE_NONE:
- if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
- /* Set flags to indicate usage of software mode. */
- instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_INF;
- instance->wrap_count = 0;
- instance->wrap_remaining = 0;
- }
-
- break;
-
- case ME_TRIG_TYPE_COUNT:
- if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
- if (trigger->iScanStopCount <= 0) {
- PERROR("Invalid scan stop count specified.\n");
- err = ME_ERRNO_INVALID_SCAN_STOP_ARG;
- goto ERROR;
- }
-
- /* Set flags to indicate usage of software mode. */
- instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_FIN;
- instance->wrap_count = trigger->iScanStopCount;
- instance->wrap_remaining = trigger->iScanStopCount;
- } else {
- PERROR("Invalid scan stop trigger type specified.\n");
- err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- goto ERROR;
- }
-
- break;
-
- default:
- PERROR("Invalid scan stop trigger type specified.\n");
-
- err = ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
-
- goto ERROR;
-
- break;
- }
-
- switch (trigger->iAcqStopTrigType) {
-
- case ME_TRIG_TYPE_NONE:
- break;
-
- case ME_TRIG_TYPE_COUNT:
- if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
- PERROR("Invalid acq stop trigger type specified.\n");
- err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- goto ERROR;
- }
-
- if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
- if (trigger->iAcqStopCount <= 0) {
- PERROR("Invalid acq stop count specified.\n");
- err = ME_ERRNO_INVALID_ACQ_STOP_ARG;
- goto ERROR;
- }
-
- /* Set flags to indicate usage of software mode. */
- instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_FIN;
- instance->wrap_count = trigger->iAcqStopCount;
- instance->wrap_remaining = trigger->iAcqStopCount;
- } else {
- PERROR("Invalid acp stop trigger type specified.\n");
- err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- goto ERROR;
- }
-
- break;
-
- default:
- PERROR("Invalid acq stop trigger type specified.\n");
- err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- goto ERROR;
- break;
- }
-
- switch (trigger->iAcqStartTrigChan) {
-
- case ME_TRIG_CHAN_DEFAULT:
- spin_lock(instance->preload_reg_lock);
- tmp = inl(instance->preload_reg);
- tmp &= ~(0x10001 << instance->ao_idx);
- outl(tmp, instance->preload_reg);
- spin_unlock(instance->preload_reg_lock);
-
- break;
-
- case ME_TRIG_CHAN_SYNCHRONOUS:
- if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) {
- spin_lock(instance->preload_reg_lock);
- tmp = inl(instance->preload_reg);
- tmp &= ~(0x10001 << instance->ao_idx);
- outl(tmp, instance->preload_reg);
- tmp |= 0x1 << instance->ao_idx;
- outl(tmp, instance->preload_reg);
- spin_unlock(instance->preload_reg_lock);
- } else {
- ctrl &= ~(ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
- spin_lock(instance->preload_reg_lock);
- tmp = inl(instance->preload_reg);
- tmp &= ~(0x10001 << instance->ao_idx);
- outl(tmp, instance->preload_reg);
- tmp |= 0x10000 << instance->ao_idx;
- outl(tmp, instance->preload_reg);
- spin_unlock(instance->preload_reg_lock);
- }
-
- break;
-
- default:
- PERROR("Invalid acq start trigger channel specified.\n");
- err = ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
- goto ERROR;
-
- break;
- }
-
- outl(conv_ticks - 2, instance->timer_reg);
-
- if (flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) {
- if (instance->ao_idx == 3) {
- ctrl |= ME4600_AO_CTRL_BIT_ENABLE_DO;
- } else {
- err = ME_ERRNO_INVALID_FLAGS;
- goto ERROR;
- }
- } else {
- if (instance->ao_idx == 3) {
- ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_DO;
- }
- }
-
- /* Set hardware mode. */
- if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
- ctrl |= ME4600_AO_CTRL_BIT_MODE_0;
- } else {
- ctrl |= ME4600_AO_CTRL_BIT_MODE_1;
- }
-
- PDEBUG("Preload word = 0x%X.\n", inl(instance->preload_reg));
-
- PDEBUG("Ctrl word = 0x%lX.\n", ctrl);
- outl(ctrl, instance->ctrl_reg); // Write the control word
-
-ERROR:
-
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
- struct file *filep,
- int time_out, int *count, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- long t = 0;
- long j;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (time_out < 0) {
- PERROR("Invalid time_out specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- t = (time_out * HZ) / 1000;
-
- if (t == 0)
- t = 1;
- }
-
- *count = 0;
-
- ME_SUBDEVICE_ENTER;
-
- if (t) {
- j = jiffies;
- wait_event_interruptible_timeout(instance->wait_queue,
- ((me_circ_buf_space
- (&instance->circ_buf))
- || !(inl(instance->status_reg)
- &
- ME4600_AO_STATUS_BIT_FSM)),
- t);
-
- if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
- PERROR("AO subdevice is not running.\n");
- err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
- } else if (signal_pending(current)) {
- PERROR("Wait on values interrupted from signal.\n");
- err = ME_ERRNO_SIGNAL;
- } else if ((jiffies - j) >= t) {
- PERROR("Wait on values timed out.\n");
- err = ME_ERRNO_TIMEOUT;
- } else {
- *count = me_circ_buf_space(&instance->circ_buf);
- }
- } else {
- wait_event_interruptible(instance->wait_queue,
- ((me_circ_buf_space
- (&instance->circ_buf))
- || !(inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)));
-
- if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
- PERROR("AO subdevice is not running.\n");
- err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
- } else if (signal_pending(current)) {
- PERROR("Wait on values interrupted from signal.\n");
- err = ME_ERRNO_SIGNAL;
- } else {
- *count = me_circ_buf_space(&instance->circ_buf);
- }
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static void stop_immediately(me4600_ao_subdevice_t *instance)
-{
- unsigned long cpu_flags;
- uint32_t tmp;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- tmp = inl(instance->ctrl_reg);
- tmp |= ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, instance->ctrl_reg);
-
- while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ;
-
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-}
-
-static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
- struct file *filep,
- int start_mode, int time_out, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long cpu_flags = 0;
- unsigned long ref;
- unsigned long tmp;
- unsigned long delay = 0;
- wait_queue_head_t queue;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- init_waitqueue_head(&queue);
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- delay = (time_out * HZ) / 1000;
-
- if (delay == 0)
- delay = 1;
- }
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- ME_SUBDEVICE_ENTER
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
- tmp = inl(instance->ctrl_reg);
-
- switch (tmp & (ME4600_AO_CTRL_MASK_MODE)) {
-
- case 0: // Single mode
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- PERROR("Subdevice is configured in single mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- goto ERROR;
-
- case 1: // Wraparound mode
- if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) { // Normal wraparound with external trigger
-
- if ((inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- PERROR("Conversion is already running.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- tmp &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
- ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-
- outl(tmp, instance->ctrl_reg);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- if (start_mode == ME_START_MODE_BLOCKING) {
- init_waitqueue_head(&queue);
-
- if (delay) {
- ref = jiffies;
-
- while (!
- (inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- interruptible_sleep_on_timeout
- (&queue, 1);
-
- if (signal_pending(current)) {
- PERROR
- ("Wait on start of state machine interrupted.\n");
- stop_immediately
- (instance);
- err = ME_ERRNO_SIGNAL;
- goto ERROR;
- }
-
- if (((jiffies - ref) >= delay)) {
- PERROR
- ("Timeout reached.\n");
- stop_immediately
- (instance);
- err = ME_ERRNO_TIMEOUT;
- goto ERROR;
- }
- }
- } else {
- while (!
- (inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- interruptible_sleep_on_timeout
- (&queue, 1);
-
- if (signal_pending(current)) {
- PERROR
- ("Wait on start of state machine interrupted.\n");
- stop_immediately
- (instance);
- err = ME_ERRNO_SIGNAL;
- goto ERROR;
- }
- }
- }
- } else if (start_mode == ME_START_MODE_NONBLOCKING) {
- } else {
- PERROR("Invalid start mode specified.\n");
- err = ME_ERRNO_INVALID_START_MODE;
- goto ERROR;
- }
- } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x10000 << instance->ao_idx)) { // Synchronous with external trigger
-
- if ((inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- PERROR("Conversion is already running.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
- tmp |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
- tmp &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
- ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
- outl(tmp, instance->ctrl_reg);
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
-
- if (start_mode == ME_START_MODE_BLOCKING) {
- init_waitqueue_head(&queue);
-
- if (delay) {
- ref = jiffies;
-
- while (!
- (inl
- (instance->
- status_reg) &
- ME4600_AO_STATUS_BIT_FSM))
- {
- interruptible_sleep_on_timeout
- (&queue, 1);
-
- if (signal_pending
- (current)) {
- PERROR
- ("Wait on start of state machine interrupted.\n");
- stop_immediately
- (instance);
- err =
- ME_ERRNO_SIGNAL;
- goto ERROR;
- }
-
- if (((jiffies - ref) >=
- delay)) {
- PERROR
- ("Timeout reached.\n");
- stop_immediately
- (instance);
- err =
- ME_ERRNO_TIMEOUT;
- goto ERROR;
- }
- }
- } else {
- while (!
- (inl
- (instance->
- status_reg) &
- ME4600_AO_STATUS_BIT_FSM))
- {
- interruptible_sleep_on_timeout
- (&queue, 1);
-
- if (signal_pending
- (current)) {
- PERROR
- ("Wait on start of state machine interrupted.\n");
- stop_immediately
- (instance);
- err =
- ME_ERRNO_SIGNAL;
- goto ERROR;
- }
- }
- }
- } else if (start_mode ==
- ME_START_MODE_NONBLOCKING) {
- } else {
- PERROR
- ("Invalid start mode specified.\n");
- err = ME_ERRNO_INVALID_START_MODE;
- goto ERROR;
- }
- } else {
- tmp &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
- ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
- outl(tmp, instance->ctrl_reg);
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- }
- } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x1 << instance->ao_idx)) { // Synchronous wraparound with sw trigger
-
- if ((inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- PERROR("Conversion is already running.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- tmp &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
- ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-
- outl(tmp, instance->ctrl_reg);
-
- if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
- outl(0x8000, instance->single_reg);
- instance->single_value = 0x8000;
- }
-
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- } else { // Software start
-
- if ((inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- PERROR("Conversion is already running.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- tmp &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
- ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-
- outl(tmp, instance->ctrl_reg);
-
- outl(0x8000, instance->single_reg);
- instance->single_value = 0x8000;
-
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- }
-
- break;
-
- case 2: // Continuous mode
- if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) { // Externally triggered
-
- if ((inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- PERROR("Conversion is already running.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- tmp &=
- ~(ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
- tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- outl(tmp, instance->ctrl_reg);
- instance->wrap_remaining = instance->wrap_count;
- instance->circ_buf.tail = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- if (start_mode == ME_START_MODE_BLOCKING) {
- init_waitqueue_head(&queue);
-
- if (delay) {
- ref = jiffies;
-
- while (!
- (inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- interruptible_sleep_on_timeout
- (&queue, 1);
-
- if (signal_pending(current)) {
- PERROR
- ("Wait on start of state machine interrupted.\n");
- stop_immediately
- (instance);
- err = ME_ERRNO_SIGNAL;
- goto ERROR;
- }
-
- if (((jiffies - ref) >= delay)) {
- PERROR
- ("Timeout reached.\n");
- stop_immediately
- (instance);
- err = ME_ERRNO_TIMEOUT;
- goto ERROR;
- }
- }
- } else {
- while (!
- (inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- interruptible_sleep_on_timeout
- (&queue, 1);
-
- if (signal_pending(current)) {
- PERROR
- ("Wait on start of state machine interrupted.\n");
- stop_immediately
- (instance);
- err = ME_ERRNO_SIGNAL;
- goto ERROR;
- }
- }
- }
- } else if (start_mode == ME_START_MODE_NONBLOCKING) {
- /* Do nothing */
- } else {
- PERROR("Invalid start mode specified.\n");
- stop_immediately(instance);
- err = ME_ERRNO_INVALID_START_MODE;
- goto ERROR;
- }
- } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x10000 << instance->ao_idx)) { // Synchronous with external trigger
-
- if ((inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- PERROR("Conversion is already running.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
- tmp |=
- ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG |
- ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- tmp &=
- ~(ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
- outl(tmp, instance->ctrl_reg);
- instance->wrap_remaining = instance->wrap_count;
- instance->circ_buf.tail = 0;
-
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
-
- if (start_mode == ME_START_MODE_BLOCKING) {
- init_waitqueue_head(&queue);
-
- if (delay) {
- ref = jiffies;
-
- while (!
- (inl
- (instance->
- status_reg) &
- ME4600_AO_STATUS_BIT_FSM))
- {
- interruptible_sleep_on_timeout
- (&queue, 1);
-
- if (signal_pending
- (current)) {
- PERROR
- ("Wait on start of state machine interrupted.\n");
- stop_immediately
- (instance);
- err =
- ME_ERRNO_SIGNAL;
- goto ERROR;
- }
-
- if (((jiffies - ref) >=
- delay)) {
- PERROR
- ("Timeout reached.\n");
- stop_immediately
- (instance);
- err =
- ME_ERRNO_TIMEOUT;
- goto ERROR;
- }
- }
- } else {
- while (!
- (inl
- (instance->
- status_reg) &
- ME4600_AO_STATUS_BIT_FSM))
- {
- interruptible_sleep_on_timeout
- (&queue, 1);
-
- if (signal_pending
- (current)) {
- PERROR
- ("Wait on start of state machine interrupted.\n");
- stop_immediately
- (instance);
- err =
- ME_ERRNO_SIGNAL;
- goto ERROR;
- }
- }
- }
- } else if (start_mode ==
- ME_START_MODE_NONBLOCKING) {
- } else {
- PERROR
- ("Invalid start mode specified.\n");
- stop_immediately(instance);
- err = ME_ERRNO_INVALID_START_MODE;
- goto ERROR;
- }
- } else {
- tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- tmp &=
- ~(ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
- outl(tmp, instance->ctrl_reg);
- instance->wrap_remaining = instance->wrap_count;
- instance->circ_buf.tail = 0;
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- }
- } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x1 << instance->ao_idx)) { // Synchronous wraparound with sw trigger
-
- if ((inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- PERROR("Conversion is already running.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- tmp &=
- ~(ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
- tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- instance->wrap_remaining = instance->wrap_count;
- instance->circ_buf.tail = 0;
- PDEBUG("CTRL Reg = 0x%X.\n", inl(instance->ctrl_reg));
- outl(tmp, instance->ctrl_reg);
-
- if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
- outl(0x8000, instance->single_reg);
- instance->single_value = 0x8000;
- }
-
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- } else { // Software start
-
- if ((inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- PERROR("Conversion is already running.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- tmp &=
- ~(ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-
- tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- outl(tmp, instance->ctrl_reg);
- outl(0x8000, instance->single_reg);
- instance->single_value = 0x8000;
- instance->wrap_remaining = instance->wrap_count;
- instance->circ_buf.tail = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- }
-
- break;
-
- default:
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- PERROR("Invalid mode configured.\n");
- err = ME_ERRNO_INTERNAL;
- goto ERROR;
- }
-
-ERROR:
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
- struct file *filep,
- int wait,
- int *status, int *values, int flags)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- wait_queue_head_t queue;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- init_waitqueue_head(&queue);
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (wait == ME_WAIT_NONE) {
- *status =
- (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ?
- ME_STATUS_BUSY : ME_STATUS_IDLE;
- *values = me_circ_buf_space(&instance->circ_buf);
- } else if (wait == ME_WAIT_IDLE) {
- while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) {
- interruptible_sleep_on_timeout(&queue, 1);
-
- if (instance->flags & ME4600_AO_FLAGS_BROKEN_PIPE) {
- PERROR("Output stream was interrupted.\n");
- *status = ME_STATUS_ERROR;
- err = ME_ERRNO_SUCCESS;
- goto ERROR;
- }
-
- if (signal_pending(current)) {
- PERROR
- ("Wait on state machine interrupted by signal.\n");
- *status = ME_STATUS_INVALID;
- err = ME_ERRNO_SIGNAL;
- goto ERROR;
- }
- }
-
- *status = ME_STATUS_IDLE;
-
- *values = me_circ_buf_space(&instance->circ_buf);
- } else {
- PERROR("Invalid wait argument specified.\n");
- *status = ME_STATUS_INVALID;
- err = ME_ERRNO_INVALID_WAIT;
- goto ERROR;
- }
-
-ERROR:
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
- struct file *filep,
- int stop_mode, int flags)
-{
- int err = ME_ERRNO_SUCCESS;
- me4600_ao_subdevice_t *instance;
- unsigned long cpu_flags;
- unsigned long tmp;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (stop_mode == ME_STOP_MODE_IMMEDIATE) {
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- tmp = inl(instance->ctrl_reg);
- tmp |=
- ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, instance->ctrl_reg);
-
- while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ;
-
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- tmp = inl(instance->ctrl_reg);
- tmp |= ME4600_AO_CTRL_BIT_STOP;
- outl(tmp, instance->ctrl_reg);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- } else {
- PERROR("Invalid stop mode specified.\n");
- err = ME_ERRNO_INVALID_STOP_MODE;
- goto ERROR;
- }
-
-ERROR:
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
- struct file *filep,
- int write_mode,
- int *values, int *count, int flags)
-{
- int err = ME_ERRNO_SUCCESS;
- me4600_ao_subdevice_t *instance;
- unsigned long tmp;
- int i;
- int value;
- int cnt = *count;
- int c;
- int k;
- int ret = 0;
- unsigned long cpu_flags = 0;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- if (!instance->fifo) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (*count <= 0) {
- PERROR("Invalid count of values specified.\n");
- err = ME_ERRNO_INVALID_VALUE_COUNT;
- goto ERROR;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
- tmp = inl(instance->ctrl_reg);
-
- switch (tmp & 0x3) {
-
- case 1: // Wraparound mode
- if (instance->bosch_fw) { // Bosch firmware
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- if (cnt != 7) {
- PERROR
- ("Invalid count of values specified. 7 expected.\n");
- err = ME_ERRNO_INVALID_VALUE_COUNT;
- goto ERROR;
- }
-
- for (i = 0; i < 7; i++) {
- if (get_user(value, values)) {
- PERROR
- ("Can't copy value from user space.\n");
- err = ME_ERRNO_INTERNAL;
- goto ERROR;
- }
-
- if (i == 0) {
- /* Maximum voltage */
- value <<= 16;
- value |=
- inl(instance->reg_base +
- 0xD4) & 0xFFFF;
- outl(value, instance->reg_base + 0xD4);
- } else if (i == 1) {
- /* Minimum voltage */
- value &= 0xFFFF;
- value |=
- inl(instance->reg_base +
- 0xD4) & 0xFFFF0000;
- outl(value, instance->reg_base + 0xD4);
- } else if (i == 2) {
- /* Delta up */
- value <<= 16;
- value |=
- inl(instance->reg_base +
- 0xD8) & 0xFFFF;
- outl(value, instance->reg_base + 0xD8);
- } else if (i == 3) {
- /* Delta down */
- value &= 0xFFFF;
- value |=
- inl(instance->reg_base +
- 0xD8) & 0xFFFF0000;
- outl(value, instance->reg_base + 0xD8);
- } else if (i == 4) {
- /* Start value */
- outl(value, instance->reg_base + 0xDC);
- } else if (i == 5) {
- /* Invert */
- if (value) {
- value = inl(instance->ctrl_reg);
- value |= 0x100;
- outl(value, instance->ctrl_reg);
- } else {
- value = inl(instance->ctrl_reg);
- value &= ~0x100;
- outl(value, instance->ctrl_reg);
- }
- } else if (i == 6) {
- /* Timer for positive ramp */
- outl(value, instance->reg_base + 0xE0);
- }
-
- values++;
- }
- } else { // Normal firmware
- PDEBUG("Write for wraparound mode.\n");
-
- if (inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM) {
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- PERROR
- ("There is already a conversion running.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- tmp |= ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO;
- outl(tmp, instance->ctrl_reg);
- tmp |= ME4600_AO_CTRL_BIT_ENABLE_FIFO;
-
- if ((*count > ME4600_AO_FIFO_COUNT) ||
- ((instance->
- flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
- ME4600_AO_FLAGS_SW_WRAP_MODE_FIN)) {
- tmp &=
- ~(ME4600_AO_CTRL_BIT_MODE_0 |
- ME4600_AO_CTRL_BIT_MODE_1);
- tmp |= ME4600_AO_CTRL_BIT_MODE_1;
- }
-
- outl(tmp, instance->ctrl_reg);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- if ((*count <= ME4600_AO_FIFO_COUNT) &&
- ((instance->
- flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
- ME4600_AO_FLAGS_SW_WRAP_MODE_INF)) {
- for (i = 0; i < *count; i++) {
- if (get_user(value, values + i)) {
- PERROR
- ("Cannot copy value from user space.\n");
- err = ME_ERRNO_INTERNAL;
- goto ERROR;
- }
-
- if (instance->ao_idx & 0x1)
- value <<= 16;
-
- outl(value, instance->fifo_reg);
- }
- } else if ((*count <= ME4600_AO_CIRC_BUF_COUNT) &&
- ((instance->
- flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK)
- == ME4600_AO_FLAGS_SW_WRAP_MODE_INF)) {
- for (i = 0; i < *count; i++) {
- if (get_user(value, values + i)) {
- PERROR
- ("Cannot copy value from user space.\n");
- err = ME_ERRNO_INTERNAL;
- goto ERROR;
- }
-
- instance->circ_buf.buf[i] = value; /* Used to hold the values. */
- }
-
- instance->circ_buf.tail = 0; /* Used as the current read position. */
- instance->circ_buf.head = *count; /* Used as the buffer size. */
-
- /* Preload the FIFO. */
-
- for (i = 0; i < ME4600_AO_FIFO_COUNT;
- i++, instance->circ_buf.tail++) {
- if (instance->circ_buf.tail >=
- instance->circ_buf.head)
- instance->circ_buf.tail = 0;
-
- if (instance->ao_idx & 0x1)
- outl(instance->circ_buf.
- buf[instance->circ_buf.
- tail] << 16,
- instance->fifo_reg);
- else
- outl(instance->circ_buf.
- buf[instance->circ_buf.
- tail],
- instance->fifo_reg);
- }
- } else if ((*count <= ME4600_AO_CIRC_BUF_COUNT) &&
- ((instance->
- flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK)
- == ME4600_AO_FLAGS_SW_WRAP_MODE_FIN)) {
- unsigned int preload_count;
-
- for (i = 0; i < *count; i++) {
- if (get_user(value, values + i)) {
- PERROR
- ("Cannot copy value from user space.\n");
- err = ME_ERRNO_INTERNAL;
- goto ERROR;
- }
-
- instance->circ_buf.buf[i] = value; /* Used to hold the values. */
- }
-
- instance->circ_buf.tail = 0; /* Used as the current read position. */
- instance->circ_buf.head = *count; /* Used as the buffer size. */
-
- /* Try to preload the whole FIFO. */
- preload_count = ME4600_AO_FIFO_COUNT;
-
- if (preload_count > instance->wrap_count)
- preload_count = instance->wrap_count;
-
- /* Preload the FIFO. */
- for (i = 0; i < preload_count;
- i++, instance->circ_buf.tail++) {
- if (instance->circ_buf.tail >=
- instance->circ_buf.head)
- instance->circ_buf.tail = 0;
-
- if (instance->ao_idx & 0x1)
- outl(instance->circ_buf.
- buf[instance->circ_buf.
- tail] << 16,
- instance->fifo_reg);
- else
- outl(instance->circ_buf.
- buf[instance->circ_buf.
- tail],
- instance->fifo_reg);
- }
-
- instance->wrap_remaining =
- instance->wrap_count - preload_count;
- } else {
- PERROR("To many values written.\n");
- err = ME_ERRNO_INVALID_VALUE_COUNT;
- goto ERROR;
- }
- }
-
- break;
-
- case 2: // Continuous mode
- /* Check if in SW wrapround mode */
- if (instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) {
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- PERROR("Subdevice is configured SW wrapround mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- goto ERROR;
- }
-
- switch (write_mode) {
-
- case ME_WRITE_MODE_BLOCKING:
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- PDEBUG("Write for blocking continuous mode.\n");
-
- while (cnt > 0) {
- wait_event_interruptible(instance->wait_queue,
- (c =
- me_circ_buf_space_to_end
- (&instance->
- circ_buf)));
-
- if (instance->
- flags & ME4600_AO_FLAGS_BROKEN_PIPE) {
- PERROR
- ("Broken pipe in blocking write.\n");
- err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
- goto ERROR;
- } else if (signal_pending(current)) {
- PERROR
- ("Wait for free buffer interrupted from signal.\n");
- err = ME_ERRNO_SIGNAL;
- goto ERROR;
- }
-
- PDEBUG("Space to end = %d.\n", c);
-
- /* Only able to write size of free buffer or size of count */
-
- if (cnt < c)
- c = cnt;
- k = sizeof(int) * c;
- k -= copy_from_user(instance->circ_buf.buf +
- instance->circ_buf.head,
- values, k);
- c = k / sizeof(int);
-
- PDEBUG("Copy %d values from user space.\n", c);
-
- if (!c) {
- PERROR
- ("Cannot copy values from user space.\n");
- err = ME_ERRNO_INTERNAL;
- goto ERROR;
- }
-
- instance->circ_buf.head =
- (instance->circ_buf.head +
- c) & (instance->circ_buf.mask);
-
- values += c;
- cnt -= c;
- ret += c;
-
- /* Values are now available so enable interrupts */
- spin_lock_irqsave(&instance->subdevice_lock,
- cpu_flags);
-
- if (me_circ_buf_space(&instance->circ_buf)) {
- tmp = inl(instance->ctrl_reg);
- tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- outl(tmp, instance->ctrl_reg);
- }
-
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- }
-
- *count = ret;
-
- break;
-
- case ME_WRITE_MODE_NONBLOCKING:
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- PDEBUG("Write for non blocking continuous mode.\n");
-
- while (cnt > 0) {
- if (instance->
- flags & ME4600_AO_FLAGS_BROKEN_PIPE) {
- PERROR
- ("ME4600:Broken pipe in nonblocking write.\n");
- err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
- goto ERROR;
- }
-
- c = me_circ_buf_space_to_end(&instance->
- circ_buf);
-
- if (!c) {
- PDEBUG
- ("Returning from nonblocking write.\n");
- break;
- }
-
- PDEBUG("Space to end = %d.\n", c);
-
- /* Only able to write size of free buffer or size of count */
-
- if (cnt < c)
- c = cnt;
- k = sizeof(int) * c;
- k -= copy_from_user(instance->circ_buf.buf +
- instance->circ_buf.head,
- values, k);
- c = k / sizeof(int);
-
- PDEBUG("Copy %d values from user space.\n", c);
-
- if (!c) {
- PERROR
- ("Cannot copy values from user space.\n");
- err = ME_ERRNO_INTERNAL;
- goto ERROR;
- }
-
- instance->circ_buf.head =
- (instance->circ_buf.head +
- c) & (instance->circ_buf.mask);
-
- values += c;
- cnt -= c;
- ret += c;
-
- /* Values are now available so enable interrupts */
- spin_lock_irqsave(&instance->subdevice_lock,
- cpu_flags);
-
- if (me_circ_buf_space(&instance->circ_buf)) {
- tmp = inl(instance->ctrl_reg);
- tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- outl(tmp, instance->ctrl_reg);
- }
-
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- }
-
- *count = ret;
-
- break;
-
- case ME_WRITE_MODE_PRELOAD:
- PDEBUG("Write for preload continuous mode.\n");
-
- if ((inl(instance->status_reg) &
- ME4600_AO_STATUS_BIT_FSM)) {
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- PERROR
- ("Can't Preload DAC FIFO while conversion is running.\n");
- err = ME_ERRNO_SUBDEVICE_BUSY;
- goto ERROR;
- }
-
- tmp = inl(instance->ctrl_reg);
-
- tmp |=
- ME4600_AO_CTRL_BIT_STOP |
- ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, instance->ctrl_reg);
- tmp &=
- ~(ME4600_AO_CTRL_BIT_ENABLE_FIFO |
- ME4600_AO_CTRL_BIT_ENABLE_IRQ);
- outl(tmp, instance->ctrl_reg);
- tmp |= ME4600_AO_CTRL_BIT_ENABLE_FIFO;
- outl(tmp, instance->ctrl_reg);
-
- instance->circ_buf.head = 0;
- instance->circ_buf.tail = 0;
- instance->flags &= ~ME4600_AO_FLAGS_BROKEN_PIPE;
-
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- c = ME4600_AO_FIFO_COUNT;
-
- if (cnt < c)
- c = cnt;
-
- for (i = 0; i < c; i++) {
- if (get_user(value, values)) {
- PERROR
- ("Can't copy value from user space.\n");
- err = ME_ERRNO_INTERNAL;
- goto ERROR;
- }
-
- if (instance->ao_idx & 0x1)
- value <<= 16;
-
- outl(value, instance->fifo_reg);
-
- values++;
- }
-
- cnt -= c;
-
- ret += c;
-
- PDEBUG("Wrote %d values to fifo.\n", c);
-
- while (1) {
- c = me_circ_buf_space_to_end(&instance->
- circ_buf);
-
- if (c == 0)
- break;
-
- if (cnt < c)
- c = cnt;
-
- if (c <= 0)
- break;
-
- k = sizeof(int) * c;
-
- k -= copy_from_user(instance->circ_buf.buf +
- instance->circ_buf.head,
- values, k);
-
- c = k / sizeof(int);
-
- PDEBUG("Wrote %d values to circular buffer.\n",
- c);
-
- if (!c) {
- PERROR
- ("Can't copy values from user space.\n");
- err = ME_ERRNO_INTERNAL;
- goto ERROR;
- }
-
- instance->circ_buf.head =
- (instance->circ_buf.head +
- c) & (instance->circ_buf.mask);
-
- values += c;
- cnt -= c;
- ret += c;
- }
-
- *count = ret;
-
- break;
-
- default:
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- PERROR("Invalid write mode specified.\n");
-
- err = ME_ERRNO_INVALID_WRITE_MODE;
-
- goto ERROR;
- }
-
- break;
-
- default: // Single mode of invalid
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- PERROR("Subdevice is configured in single mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- goto ERROR;
- }
-
-ERROR:
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
-{
- unsigned long tmp;
- int value;
- me4600_ao_subdevice_t *instance = dev_id;
- int i;
- int c = 0;
- int c1 = 0;
-
- if (irq != instance->irq) {
- PDEBUG("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- if (!((0x1 << (instance->ao_idx + 3)) & inl(instance->irq_status_reg))) {
- return IRQ_NONE;
- }
-
- PDEBUG("executed.\n");
-
- tmp = inl(instance->status_reg);
-
- if (!(tmp & ME4600_AO_STATUS_BIT_EF) &&
- (tmp & ME4600_AO_STATUS_BIT_HF) &&
- (tmp & ME4600_AO_STATUS_BIT_HF)) {
- c = ME4600_AO_FIFO_COUNT;
- PDEBUG("Fifo empty.\n");
- } else if ((tmp & ME4600_AO_STATUS_BIT_EF) &&
- (tmp & ME4600_AO_STATUS_BIT_HF) &&
- (tmp & ME4600_AO_STATUS_BIT_HF)) {
- c = ME4600_AO_FIFO_COUNT / 2;
- PDEBUG("Fifo under half full.\n");
- } else {
- c = 0;
- PDEBUG("Fifo full.\n");
- }
-
- PDEBUG("Try to write 0x%04X values.\n", c);
-
- if ((instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
- ME4600_AO_FLAGS_SW_WRAP_MODE_INF) {
- while (c) {
- c1 = c;
-
- if (c1 > (instance->circ_buf.head - instance->circ_buf.tail)) /* Only up to the end of the buffer */
- c1 = (instance->circ_buf.head -
- instance->circ_buf.tail);
-
- /* Write the values to the FIFO */
- for (i = 0; i < c1; i++, instance->circ_buf.tail++, c--) {
- if (instance->ao_idx & 0x1)
- outl(instance->circ_buf.
- buf[instance->circ_buf.tail] << 16,
- instance->fifo_reg);
- else
- outl(instance->circ_buf.
- buf[instance->circ_buf.tail],
- instance->fifo_reg);
- }
-
- if (instance->circ_buf.tail >= instance->circ_buf.head) /* Start from beginning */
- instance->circ_buf.tail = 0;
- }
-
- spin_lock(&instance->subdevice_lock);
-
- tmp = inl(instance->ctrl_reg);
- tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(tmp, instance->ctrl_reg);
- tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(tmp, instance->ctrl_reg);
-
- if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
- PERROR("Broken pipe.\n");
- instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE;
- tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- outl(tmp, instance->ctrl_reg);
- }
-
- spin_unlock(&instance->subdevice_lock);
- } else if ((instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
- ME4600_AO_FLAGS_SW_WRAP_MODE_FIN) {
- while (c && instance->wrap_remaining) {
- c1 = c;
-
- if (c1 > (instance->circ_buf.head - instance->circ_buf.tail)) /* Only up to the end of the buffer */
- c1 = (instance->circ_buf.head -
- instance->circ_buf.tail);
-
- if (c1 > instance->wrap_remaining) /* Only up to count of user defined number of values */
- c1 = instance->wrap_remaining;
-
- /* Write the values to the FIFO */
- for (i = 0; i < c1;
- i++, instance->circ_buf.tail++, c--,
- instance->wrap_remaining--) {
- if (instance->ao_idx & 0x1)
- outl(instance->circ_buf.
- buf[instance->circ_buf.tail] << 16,
- instance->fifo_reg);
- else
- outl(instance->circ_buf.
- buf[instance->circ_buf.tail],
- instance->fifo_reg);
- }
-
- if (instance->circ_buf.tail >= instance->circ_buf.head) /* Start from beginning */
- instance->circ_buf.tail = 0;
- }
-
- spin_lock(&instance->subdevice_lock);
-
- tmp = inl(instance->ctrl_reg);
-
- if (!instance->wrap_remaining) {
- PDEBUG("Finite SW wraparound done.\n");
- tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- }
-
- tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-
- outl(tmp, instance->ctrl_reg);
- tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(tmp, instance->ctrl_reg);
-
- if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
- PERROR("Broken pipe.\n");
- instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE;
- tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- outl(tmp, instance->ctrl_reg);
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- } else { /* Regular continuous mode */
-
- while (1) {
- c1 = me_circ_buf_values_to_end(&instance->circ_buf);
- PDEBUG("Values to end = %d.\n", c1);
-
- if (c1 > c)
- c1 = c;
-
- if (c1 <= 0) {
- PDEBUG("Work done or buffer empty.\n");
- break;
- }
-
- if (instance->ao_idx & 0x1) {
- for (i = 0; i < c1; i++) {
- value =
- *(instance->circ_buf.buf +
- instance->circ_buf.tail +
- i) << 16;
- outl(value, instance->fifo_reg);
- }
- } else
- outsl(instance->fifo_reg,
- instance->circ_buf.buf +
- instance->circ_buf.tail, c1);
-
- instance->circ_buf.tail =
- (instance->circ_buf.tail +
- c1) & (instance->circ_buf.mask);
-
- PDEBUG("%d values wrote to port 0x%04X.\n", c1,
- instance->fifo_reg);
-
- c -= c1;
- }
-
- spin_lock(&instance->subdevice_lock);
-
- tmp = inl(instance->ctrl_reg);
-
- if (!me_circ_buf_values(&instance->circ_buf)) {
- PDEBUG
- ("Disable Interrupt because no values left in buffer.\n");
- tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- }
-
- tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-
- outl(tmp, instance->ctrl_reg);
- tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
- outl(tmp, instance->ctrl_reg);
-
- if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
- PDEBUG("Broken pipe in me4600_ao_isr.\n");
- instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE;
- tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
- outl(tmp, instance->ctrl_reg);
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- wake_up_interruptible(&instance->wait_queue);
- }
-
- return IRQ_HANDLED;
-}
-
-static void me4600_ao_destructor(struct me_subdevice *subdevice)
-{
- me4600_ao_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- free_irq(instance->irq, instance);
- kfree(instance->circ_buf.buf);
- me_subdevice_deinit(&instance->base);
- kfree(instance);
-}
-
-me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
- spinlock_t *preload_reg_lock,
- uint32_t *preload_flags,
- int ao_idx, int fifo, int irq)
-{
- me4600_ao_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me4600_ao_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me4600_ao_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->preload_reg_lock = preload_reg_lock;
- subdevice->preload_flags = preload_flags;
-
- /* Allocate and initialize circular buffer */
- subdevice->circ_buf.mask = ME4600_AO_CIRC_BUF_COUNT - 1;
- subdevice->circ_buf.buf = kmalloc(ME4600_AO_CIRC_BUF_SIZE, GFP_KERNEL);
-
- if (!subdevice->circ_buf.buf) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- me_subdevice_deinit((me_subdevice_t *) subdevice);
- kfree(subdevice);
- return NULL;
- }
-
- memset(subdevice->circ_buf.buf, 0, ME4600_AO_CIRC_BUF_SIZE);
-
- subdevice->circ_buf.head = 0;
- subdevice->circ_buf.tail = 0;
-
- /* Initialize wait queue */
- init_waitqueue_head(&subdevice->wait_queue);
-
- /* Initialize single value to 0V */
- subdevice->single_value = 0x8000;
-
- /* Store analog output index */
- subdevice->ao_idx = ao_idx;
-
- /* Store if analog output has fifo */
- subdevice->fifo = fifo;
-
- /* Initialize registers */
-
- if (ao_idx == 0) {
- subdevice->ctrl_reg = reg_base + ME4600_AO_00_CTRL_REG;
- subdevice->status_reg = reg_base + ME4600_AO_00_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME4600_AO_00_FIFO_REG;
- subdevice->single_reg = reg_base + ME4600_AO_00_SINGLE_REG;
- subdevice->timer_reg = reg_base + ME4600_AO_00_TIMER_REG;
- subdevice->reg_base = reg_base;
-
- if (inl(subdevice->reg_base + ME4600_AO_BOSCH_REG) == 0x20000) {
- PINFO("Bosch firmware in use for channel 0.\n");
- subdevice->bosch_fw = 1;
- } else {
- subdevice->bosch_fw = 0;
- }
- } else if (ao_idx == 1) {
- subdevice->ctrl_reg = reg_base + ME4600_AO_01_CTRL_REG;
- subdevice->status_reg = reg_base + ME4600_AO_01_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME4600_AO_01_FIFO_REG;
- subdevice->single_reg = reg_base + ME4600_AO_01_SINGLE_REG;
- subdevice->timer_reg = reg_base + ME4600_AO_01_TIMER_REG;
- subdevice->reg_base = reg_base;
- subdevice->bosch_fw = 0;
- } else if (ao_idx == 2) {
- subdevice->ctrl_reg = reg_base + ME4600_AO_02_CTRL_REG;
- subdevice->status_reg = reg_base + ME4600_AO_02_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME4600_AO_02_FIFO_REG;
- subdevice->single_reg = reg_base + ME4600_AO_02_SINGLE_REG;
- subdevice->timer_reg = reg_base + ME4600_AO_02_TIMER_REG;
- subdevice->reg_base = reg_base;
- subdevice->bosch_fw = 0;
- } else {
- subdevice->ctrl_reg = reg_base + ME4600_AO_03_CTRL_REG;
- subdevice->status_reg = reg_base + ME4600_AO_03_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME4600_AO_03_FIFO_REG;
- subdevice->single_reg = reg_base + ME4600_AO_03_SINGLE_REG;
- subdevice->timer_reg = reg_base + ME4600_AO_03_TIMER_REG;
- subdevice->reg_base = reg_base;
- subdevice->bosch_fw = 0;
- }
-
- subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
- subdevice->preload_reg = reg_base + ME4600_AO_LOADSETREG_XX;
-
- /* Register interrupt service routine */
- subdevice->irq = irq;
-
- if (request_irq
- (subdevice->irq, me4600_ao_isr, IRQF_DISABLED | IRQF_SHARED,
- ME4600_NAME, subdevice)) {
- PERROR("Cannot get interrupt line.\n");
- me_subdevice_deinit((me_subdevice_t *) subdevice);
- kfree(subdevice->circ_buf.buf);
- kfree(subdevice);
- return NULL;
- }
-
- /* Override base class methods. */
- subdevice->base.me_subdevice_destructor = me4600_ao_destructor;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me4600_ao_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me4600_ao_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me4600_ao_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me4600_ao_io_single_write;
- subdevice->base.me_subdevice_io_stream_config =
- me4600_ao_io_stream_config;
- subdevice->base.me_subdevice_io_stream_new_values =
- me4600_ao_io_stream_new_values;
- subdevice->base.me_subdevice_io_stream_write =
- me4600_ao_io_stream_write;
- subdevice->base.me_subdevice_io_stream_start =
- me4600_ao_io_stream_start;
- subdevice->base.me_subdevice_io_stream_status =
- me4600_ao_io_stream_status;
- subdevice->base.me_subdevice_io_stream_stop = me4600_ao_io_stream_stop;
- subdevice->base.me_subdevice_query_number_channels =
- me4600_ao_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me4600_ao_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me4600_ao_query_subdevice_caps;
- subdevice->base.me_subdevice_query_subdevice_caps_args =
- me4600_ao_query_subdevice_caps_args;
- subdevice->base.me_subdevice_query_range_by_min_max =
- me4600_ao_query_range_by_min_max;
- subdevice->base.me_subdevice_query_number_ranges =
- me4600_ao_query_number_ranges;
- subdevice->base.me_subdevice_query_range_info =
- me4600_ao_query_range_info;
- subdevice->base.me_subdevice_query_timer = me4600_ao_query_timer;
-
- return subdevice;
-}
-
-#endif // BOSCH
-
-/* Common functions
-*/
-
-static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
- int unit,
- int *min,
- int *max, int *maxdata, int *range)
-{
- me4600_ao_subdevice_t *instance;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if ((*max - *min) < 0) {
- PERROR("Invalid minimum and maximum values specified.\n");
- return ME_ERRNO_INVALID_MIN_MAX;
- }
-
- if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
- if ((*max <= (ME4600_AO_MAX_RANGE + 1000))
- && (*min >= ME4600_AO_MIN_RANGE)) {
- *min = ME4600_AO_MIN_RANGE;
- *max = ME4600_AO_MAX_RANGE;
- *maxdata = ME4600_AO_MAX_DATA;
- *range = 0;
- } else {
- PERROR("No matching range available.\n");
- return ME_ERRNO_NO_RANGE;
- }
- } else {
- PERROR("Invalid physical unit specified.\n");
- return ME_ERRNO_INVALID_UNIT;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice,
- int unit, int *count)
-{
- me4600_ao_subdevice_t *instance;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
- *count = 1;
- } else {
- *count = 0;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_range_info(me_subdevice_t *subdevice,
- int range,
- int *unit,
- int *min, int *max, int *maxdata)
-{
- me4600_ao_subdevice_t *instance;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (range == 0) {
- *unit = ME_UNIT_VOLT;
- *min = ME4600_AO_MIN_RANGE;
- *max = ME4600_AO_MAX_RANGE;
- *maxdata = ME4600_AO_MAX_DATA;
- } else {
- PERROR("Invalid range number specified.\n");
- return ME_ERRNO_INVALID_RANGE;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_timer(me_subdevice_t *subdevice,
- int timer,
- int *base_frequency,
- long long *min_ticks, long long *max_ticks)
-{
- me4600_ao_subdevice_t *instance;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if ((timer != ME_TIMER_ACQ_START) && (timer != ME_TIMER_CONV_START)) {
- PERROR("Invalid timer specified.\n");
- return ME_ERRNO_INVALID_TIMER;
- }
-
- if (instance->fifo) { //Streaming device.
- *base_frequency = ME4600_AO_BASE_FREQUENCY;
- if (timer == ME_TIMER_ACQ_START) {
- *min_ticks = ME4600_AO_MIN_ACQ_TICKS;
- *max_ticks = ME4600_AO_MAX_ACQ_TICKS;
- } else if (timer == ME_TIMER_CONV_START) {
- *min_ticks = ME4600_AO_MIN_CHAN_TICKS;
- *max_ticks = ME4600_AO_MAX_CHAN_TICKS;
- }
- } else { //Not streaming device!
- *base_frequency = 0;
- *min_ticks = 0;
- *max_ticks = 0;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- me4600_ao_subdevice_t *instance;
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- *number = 1;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- me4600_ao_subdevice_t *instance;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- *type = ME_TYPE_AO;
- *subtype = (instance->fifo) ? ME_SUBTYPE_STREAMING : ME_SUBTYPE_SINGLE;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- me4600_ao_subdevice_t *instance;
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- *caps =
- ME_CAPS_AO_TRIG_SYNCHRONOUS | ((instance->fifo) ? ME_CAPS_AO_FIFO :
- ME_CAPS_NONE);
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
- int cap, int *args, int count)
-{
- me4600_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- instance = (me4600_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (count != 1) {
- PERROR("Invalid capability argument count.\n");
- return ME_ERRNO_INVALID_CAP_ARG_COUNT;
- }
-
- switch (cap) {
- case ME_CAP_AI_FIFO_SIZE:
- args[0] = (instance->fifo) ? ME4600_AO_FIFO_COUNT : 0;
- break;
-
- case ME_CAP_AI_BUFFER_SIZE:
- args[0] =
- (instance->circ_buf.buf) ? ME4600_AO_CIRC_BUF_COUNT : 0;
- break;
-
- default:
- PERROR("Invalid capability.\n");
- err = ME_ERRNO_INVALID_CAP;
- args[0] = 0;
- }
-
- return err;
-}
diff --git a/drivers/staging/meilhaus/me4600_ao.h b/drivers/staging/meilhaus/me4600_ao.h
deleted file mode 100644
index 7579435..0000000
--- a/drivers/staging/meilhaus/me4600_ao.h
+++ /dev/null
@@ -1,259 +0,0 @@
-/**
- * @file me4600_ao.h
- *
- * @brief Meilhaus ME-4000 analog output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_AO_H_
-# define _ME4600_AO_H_
-
-# include <linux/version.h>
-# include "mesubdevice.h"
-# include "mecirc_buf.h"
-# include "meioctl.h"
-
-# ifdef __KERNEL__
-
-# ifdef BOSCH
-# undef ME_SYNAPSE
-# ifndef _CBUFF_32b_t
-# define _CBUFF_32b_t
-# endif //_CBUFF_32b_t
-# endif //BOSCH
-
-# define ME4600_AO_MAX_SUBDEVICES 4
-# define ME4600_AO_FIFO_COUNT 4096
-
-# define ME4600_AO_BASE_FREQUENCY 33000000LL
-
-# define ME4600_AO_MIN_ACQ_TICKS 0LL
-# define ME4600_AO_MAX_ACQ_TICKS 0LL
-
-# define ME4600_AO_MIN_CHAN_TICKS 66LL
-# define ME4600_AO_MAX_CHAN_TICKS 0xFFFFFFFFLL
-
-# define ME4600_AO_MIN_RANGE -10000000
-# define ME4600_AO_MAX_RANGE 9999694
-
-# define ME4600_AO_MAX_DATA 0xFFFF
-
-# ifdef ME_SYNAPSE
-# define ME4600_AO_CIRC_BUF_SIZE_ORDER 8 // 2^n PAGES =>> Maximum value of 1MB for Synapse
-# else
-# define ME4600_AO_CIRC_BUF_SIZE_ORDER 5 // 2^n PAGES =>> 128KB
-# endif
-# define ME4600_AO_CIRC_BUF_SIZE PAGE_SIZE<<ME4600_AO_CIRC_BUF_SIZE_ORDER // Buffer size in bytes.
-
-# ifdef _CBUFF_32b_t
-# define ME4600_AO_CIRC_BUF_COUNT ((ME4600_AO_CIRC_BUF_SIZE) / sizeof(uint32_t)) // Size in values
-# else
-# define ME4600_AO_CIRC_BUF_COUNT ((ME4600_AO_CIRC_BUF_SIZE) / sizeof(uint16_t)) // Size in values
-# endif
-
-# define ME4600_AO_CONTINOUS 0x0
-# define ME4600_AO_WRAP_MODE 0x1
-# define ME4600_AO_HW_MODE 0x2
-
-# define ME4600_AO_HW_WRAP_MODE (ME4600_AO_WRAP_MODE | ME4600_AO_HW_MODE)
-# define ME4600_AO_SW_WRAP_MODE ME4600_AO_WRAP_MODE
-
-# define ME4600_AO_INF_STOP_MODE 0x0
-# define ME4600_AO_ACQ_STOP_MODE 0x1
-# define ME4600_AO_SCAN_STOP_MODE 0x2
-
-# ifdef BOSCH //SPECIAL BUILD FOR BOSCH
-
-/* Bits for flags attribute. */
-# define ME4600_AO_FLAGS_BROKEN_PIPE 0x1
-# define ME4600_AO_FLAGS_SW_WRAP_MODE_0 0x2
-# define ME4600_AO_FLAGS_SW_WRAP_MODE_1 0x4
-# define ME4600_AO_FLAGS_SW_WRAP_MODE_MASK (ME4600_AO_FLAGS_SW_WRAP_MODE_0 | ME4600_AO_FLAGS_SW_WRAP_MODE_1)
-
-# define ME4600_AO_FLAGS_SW_WRAP_MODE_NONE 0x0
-# define ME4600_AO_FLAGS_SW_WRAP_MODE_INF 0x2
-# define ME4600_AO_FLAGS_SW_WRAP_MODE_FIN 0x4
-
- /**
- * @brief The ME-4000 analog output subdevice class.
- */
-typedef struct me4600_ao_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *preload_reg_lock; /**< Spin lock to protect #preload_reg from concurrent access. */
- uint32_t *preload_flags;
-
- unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */
- me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. */
- wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
-
- int single_value; /**< Mirror of the value written in single mode. */
-
- int volatile flags; /**< Flags used for storing SW wraparound setup and error signalling from ISR. */
- unsigned int wrap_count; /**< The user defined wraparound cycle count. */
- unsigned int wrap_remaining; /**< The wraparound cycle down counter used by a running conversion. */
- unsigned int ao_idx; /**< The index of this analog output on this device. */
- int fifo; /**< If set this device has a FIFO. */
-
- int bosch_fw; /**< If set the bosch firmware is in PROM. */
-
- /* Registers */
- uint32_t ctrl_reg;
- uint32_t status_reg;
- uint32_t fifo_reg;
- uint32_t single_reg;
- uint32_t timer_reg;
- uint32_t irq_status_reg;
- uint32_t preload_reg;
- uint32_t reg_base;
-} me4600_ao_subdevice_t;
-
- /**
- * @brief The constructor to generate a ME-4000 analog output subdevice instance for BOSCH project.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
- * @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
- * @param ao_idx Subdevice number.
- * @param fifo Flag set if subdevice has hardware FIFO.
- * @param irq IRQ number.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
- spinlock_t * preload_reg_lock,
- uint32_t * preload_flags,
- int ao_idx, int fifo, int irq);
-
-# else //~BOSCH
-
-//ME4600_AO_FLAGS_BROKEN_PIPE is OBSOLETE => Now problems are reported in status.
-
-typedef enum ME4600_AO_STATUS {
- ao_status_none = 0,
- ao_status_single_configured,
- ao_status_single_run_wait,
- ao_status_single_run,
- ao_status_single_end_wait,
- ao_status_single_end,
- ao_status_stream_configured,
- ao_status_stream_run_wait,
- ao_status_stream_run,
- ao_status_stream_end_wait,
- ao_status_stream_end,
- ao_status_stream_fifo_error,
- ao_status_stream_buffer_error,
- ao_status_stream_error,
- ao_status_last
-} ME4600_AO_STATUS;
-
-typedef struct me4600_ao_timeout {
- unsigned long start_time;
- unsigned long delay;
-} me4600_ao_timeout_t;
-
- /**
- * @brief The ME-4600 analog output subdevice class.
- */
-typedef struct me4600_ao_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
- unsigned int ao_idx; /**< The index of this analog output on this device. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *preload_reg_lock; /**< Spin lock to protect preload_reg from concurrent access. */
-
- uint32_t *preload_flags;
-
- /* Hardware feautres */
- unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */
- int fifo; /**< If set this device has a FIFO. */
- int bitpattern; /**< If set this device use bitpattern. */
-
- int single_value; /**< Mirror of the output value in single mode. */
- int single_value_in_fifo; /**< Mirror of the value written in single mode. */
- uint32_t ctrl_trg; /**< Mirror of the trigger settings. */
-
- volatile int mode; /**< Flags used for storing SW wraparound setup*/
- int stop_mode; /**< The user defined stop condition flag. */
- unsigned int start_mode;
- unsigned int stop_count; /**< The user defined dates presentation end count. */
- unsigned int stop_data_count; /**< The stop presentation count. */
- unsigned int data_count; /**< The real presentation count. */
- unsigned int preloaded_count; /**< The next data addres in buffer. <= for wraparound mode. */
- int hardware_stop_delay; /**< The time that stop can take. This is only to not show hardware bug to user. */
-
- volatile enum ME4600_AO_STATUS status; /**< The current stream status flag. */
- me4600_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
-
- /* Registers *//**< All registers are 32 bits long. */
- unsigned long ctrl_reg;
- unsigned long status_reg;
- unsigned long fifo_reg;
- unsigned long single_reg;
- unsigned long timer_reg;
- unsigned long irq_status_reg;
- unsigned long preload_reg;
- unsigned long reg_base;
-
- /* Software buffer */
- me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. 32 bit long */
- wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
-
- struct workqueue_struct *me4600_workqueue;
- struct delayed_work ao_control_task;
-
- volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
-
-} me4600_ao_subdevice_t;
-
- /**
- * @brief The constructor to generate a ME-4600 analog output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
- * @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
- * @param ao_idx Subdevice number.
- * @param fifo Flag set if subdevice has hardware FIFO.
- * @param irq IRQ number.
- * @param me4600_wq Queue for asynchronous task (1 queue for all subdevice on 1 board).
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
- spinlock_t * preload_reg_lock,
- uint32_t * preload_flags,
- int ao_idx,
- int fifo,
- int irq,
- struct workqueue_struct
- *me4600_wq);
-
-# endif //BOSCH
-# endif //__KERNEL__
-#endif // ~_ME4600_AO_H_
diff --git a/drivers/staging/meilhaus/me4600_ao_reg.h b/drivers/staging/meilhaus/me4600_ao_reg.h
deleted file mode 100644
index f83d82e..0000000
--- a/drivers/staging/meilhaus/me4600_ao_reg.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * @file me4600_ao_reg.h
- *
- * @brief ME-4000 analog output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_AO_REG_H_
-#define _ME4600_AO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME4600_AO_00_CTRL_REG 0x00 // R/W
-#define ME4600_AO_00_STATUS_REG 0x04 // R/_
-#define ME4600_AO_00_FIFO_REG 0x08 // _/W
-#define ME4600_AO_00_SINGLE_REG 0x0C // R/W
-#define ME4600_AO_00_TIMER_REG 0x10 // _/W
-
-#define ME4600_AO_01_CTRL_REG 0x18 // R/W
-#define ME4600_AO_01_STATUS_REG 0x1C // R/_
-#define ME4600_AO_01_FIFO_REG 0x20 // _/W
-#define ME4600_AO_01_SINGLE_REG 0x24 // R/W
-#define ME4600_AO_01_TIMER_REG 0x28 // _/W
-
-#define ME4600_AO_02_CTRL_REG 0x30 // R/W
-#define ME4600_AO_02_STATUS_REG 0x34 // R/_
-#define ME4600_AO_02_FIFO_REG 0x38 // _/W
-#define ME4600_AO_02_SINGLE_REG 0x3C // R/W
-#define ME4600_AO_02_TIMER_REG 0x40 // _/W
-
-#define ME4600_AO_03_CTRL_REG 0x48 // R/W
-#define ME4600_AO_03_STATUS_REG 0x4C // R/_
-#define ME4600_AO_03_FIFO_REG 0x50 // _/W
-#define ME4600_AO_03_SINGLE_REG 0x54 // R/W
-#define ME4600_AO_03_TIMER_REG 0x58 // _/W
-
-#define ME4600_AO_DEMUX_ADJUST_REG 0xBC // -/W
-#define ME4600_AO_DEMUX_ADJUST_VALUE 0x4C
-
-#ifdef BOSCH
-# define ME4600_AO_BOSCH_REG 0xC4
-
-# define ME4600_AO_LOADSETREG_XX 0xB4 // R/W
-
-# define ME4600_AO_CTRL_BIT_MODE_0 0x001
-# define ME4600_AO_CTRL_BIT_MODE_1 0x002
-# define ME4600_AO_CTRL_MASK_MODE 0x003
-
-#else //~BOSCH
-
-#define ME4600_AO_SYNC_REG 0xB4 // R/W ///ME4600_AO_SYNC_REG <==> ME4600_AO_PRELOAD_REG <==> ME4600_AO_LOADSETREG_XX
-
-# define ME4600_AO_MODE_SINGLE 0x00000000
-# define ME4600_AO_MODE_WRAPAROUND 0x00000001
-# define ME4600_AO_MODE_CONTINUOUS 0x00000002
-# define ME4600_AO_CTRL_MODE_MASK (ME4600_AO_MODE_WRAPAROUND | ME4600_AO_MODE_CONTINUOUS)
-#endif //BOSCH
-
-#define ME4600_AO_CTRL_BIT_MODE_WRAPAROUND ME4600_AO_MODE_WRAPAROUND
-#define ME4600_AO_CTRL_BIT_MODE_CONTINOUS ME4600_AO_MODE_CONTINUOUS
-#define ME4600_AO_CTRL_BIT_STOP 0x00000004
-#define ME4600_AO_CTRL_BIT_ENABLE_FIFO 0x00000008
-#define ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG 0x00000010
-#define ME4600_AO_CTRL_BIT_EX_TRIG_EDGE 0x00000020
-#define ME4600_AO_CTRL_BIT_IMMEDIATE_STOP 0x00000080
-#define ME4600_AO_CTRL_BIT_ENABLE_DO 0x00000100
-#define ME4600_AO_CTRL_BIT_ENABLE_IRQ 0x00000200
-#define ME4600_AO_CTRL_BIT_RESET_IRQ 0x00000400
-#define ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH 0x00000800
-/*
-#define ME4600_AO_SYNC_HOLD_0 0x00000001
-#define ME4600_AO_SYNC_HOLD_1 0x00000002
-#define ME4600_AO_SYNC_HOLD_2 0x00000004
-#define ME4600_AO_SYNC_HOLD_3 0x00000008
-*/
-#define ME4600_AO_SYNC_HOLD 0x00000001
-
-/*
-#define ME4600_AO_SYNC_EXT_TRIG_0 0x00010000
-#define ME4600_AO_SYNC_EXT_TRIG_1 0x00020000
-#define ME4600_AO_SYNC_EXT_TRIG_2 0x00040000
-#define ME4600_AO_SYNC_EXT_TRIG_3 0x00080000
-*/
-#define ME4600_AO_SYNC_EXT_TRIG 0x00010000
-
-#define ME4600_AO_EXT_TRIG 0x80000000
-
-#define ME4600_AO_STATUS_BIT_FSM 0x00000001
-#define ME4600_AO_STATUS_BIT_FF 0x00000002
-#define ME4600_AO_STATUS_BIT_HF 0x00000004
-#define ME4600_AO_STATUS_BIT_EF 0x00000008
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_device.c b/drivers/staging/meilhaus/me4600_device.c
deleted file mode 100644
index 457666e..0000000
--- a/drivers/staging/meilhaus/me4600_device.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/**
- * @file me4600_device.c
- *
- * @brief ME-4600 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#ifndef MODULE
-# define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "me4600_device.h"
-#include "meplx_reg.h"
-
-#include "mefirmware.h"
-
-#include "mesubdevice.h"
-#include "me4600_do.h"
-#include "me4600_di.h"
-#include "me4600_dio.h"
-#include "me8254.h"
-#include "me4600_ai.h"
-#include "me4600_ao.h"
-#include "me4600_ext_irq.h"
-
-/**
- * @brief Global variable.
- * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts).
- */
-static struct workqueue_struct *me4600_workqueue;
-
-#ifdef BOSCH
-me_device_t *me4600_pci_constructor(struct pci_dev *pci_device, int me_bosch_fw)
-#else //~BOSCH
-me_device_t *me4600_pci_constructor(struct pci_dev *pci_device)
-#endif //BOSCH
-{
- me4600_device_t *me4600_device;
- me_subdevice_t *subdevice;
- unsigned int version_idx;
- int err;
- int i;
-
- PDEBUG("executed.\n");
-
- // Allocate structure for device instance.
- me4600_device = kmalloc(sizeof(me4600_device_t), GFP_KERNEL);
-
- if (!me4600_device) {
- PERROR("Cannot get memory for ME-4600 device instance.\n");
- return NULL;
- }
-
- memset(me4600_device, 0, sizeof(me4600_device_t));
-
- // Initialize base class structure.
- err = me_device_pci_init((me_device_t *) me4600_device, pci_device);
-
- if (err) {
- kfree(me4600_device);
- PERROR("Cannot initialize device base class.\n");
- return NULL;
- }
- // Download the xilinx firmware.
- if (me4600_device->base.info.pci.device_id == PCI_DEVICE_ID_MEILHAUS_ME4610) { //Jekyll <=> me4610
- err =
- me_xilinx_download(me4600_device->base.info.pci.
- reg_bases[1],
- me4600_device->base.info.pci.
- reg_bases[5], &pci_device->dev,
- "me4610.bin");
- } else { // General me4600 firmware
-#ifdef BOSCH
- err =
- me_xilinx_download(me4600_device->base.info.pci.
- reg_bases[1],
- me4600_device->base.info.pci.
- reg_bases[5], &pci_device->dev,
- (me_bosch_fw) ? "me4600_bosch.bin" :
- "me4600.bin");
-#else //~BOSCH
- err =
- me_xilinx_download(me4600_device->base.info.pci.
- reg_bases[1],
- me4600_device->base.info.pci.
- reg_bases[5], &pci_device->dev,
- "me4600.bin");
-#endif
- }
-
- if (err) {
- me_device_deinit((me_device_t *) me4600_device);
- kfree(me4600_device);
- PERROR("Cannot download firmware.\n");
- return NULL;
- }
- // Get the index in the device version information table.
- version_idx =
- me4600_versions_get_device_index(me4600_device->base.info.pci.
- device_id);
-
- // Initialize spin locks.
- spin_lock_init(&me4600_device->preload_reg_lock);
-
- me4600_device->preload_flags = 0;
-
- spin_lock_init(&me4600_device->dio_lock);
- spin_lock_init(&me4600_device->ai_ctrl_lock);
- spin_lock_init(&me4600_device->ctr_ctrl_reg_lock);
- spin_lock_init(&me4600_device->ctr_clk_src_reg_lock);
-
- // Create digital input instances.
- for (i = 0; i < me4600_versions[version_idx].di_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me4600_di_constructor(me4600_device->
- base.info.pci.
- reg_bases[2],
- &me4600_device->
- dio_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me4600_device);
- kfree(me4600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me4600_device->base.slist,
- subdevice);
- }
-
- // Create digital output instances.
- for (i = 0; i < me4600_versions[version_idx].do_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me4600_do_constructor(me4600_device->
- base.info.pci.
- reg_bases[2],
- &me4600_device->
- dio_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me4600_device);
- kfree(me4600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me4600_device->base.slist,
- subdevice);
- }
-
- // Create digital input/output instances.
- for (i = 0; i < me4600_versions[version_idx].dio_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me4600_dio_constructor(me4600_device->
- base.info.pci.
- reg_bases[2],
- me4600_versions
- [version_idx].
- do_subdevices +
- me4600_versions
- [version_idx].
- di_subdevices + i,
- &me4600_device->
- dio_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me4600_device);
- kfree(me4600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me4600_device->base.slist,
- subdevice);
- }
-
- // Create analog input instances.
- for (i = 0; i < me4600_versions[version_idx].ai_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me4600_ai_constructor(me4600_device->
- base.info.pci.
- reg_bases[2],
- me4600_versions
- [version_idx].
- ai_channels,
- me4600_versions
- [version_idx].
- ai_ranges,
- me4600_versions
- [version_idx].
- ai_isolated,
- me4600_versions
- [version_idx].
- ai_sh,
- me4600_device->
- base.irq,
- &me4600_device->
- ai_ctrl_lock,
- me4600_workqueue);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me4600_device);
- kfree(me4600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me4600_device->base.slist,
- subdevice);
- }
-
- // Create analog output instances.
- for (i = 0; i < me4600_versions[version_idx].ao_subdevices; i++) {
-#ifdef BOSCH
- subdevice =
- (me_subdevice_t *) me4600_ao_constructor(me4600_device->
- base.info.pci.
- reg_bases[2],
- &me4600_device->
- preload_reg_lock,
- &me4600_device->
- preload_flags, i,
- me4600_versions
- [version_idx].
- ao_fifo,
- me4600_device->
- base.irq);
-#else //~BOSCH
- subdevice =
- (me_subdevice_t *) me4600_ao_constructor(me4600_device->
- base.info.pci.
- reg_bases[2],
- &me4600_device->
- preload_reg_lock,
- &me4600_device->
- preload_flags, i,
- me4600_versions
- [version_idx].
- ao_fifo,
- me4600_device->
- base.irq,
- me4600_workqueue);
-#endif
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me4600_device);
- kfree(me4600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me4600_device->base.slist,
- subdevice);
- }
-
- // Create counter instances.
- for (i = 0; i < me4600_versions[version_idx].ctr_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me8254_constructor(me4600_device->base.
- info.pci.device_id,
- me4600_device->base.
- info.pci.reg_bases[3],
- 0, i,
- &me4600_device->
- ctr_ctrl_reg_lock,
- &me4600_device->
- ctr_clk_src_reg_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me4600_device);
- kfree(me4600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me4600_device->base.slist,
- subdevice);
- }
-
- // Create external interrupt instances.
- for (i = 0; i < me4600_versions[version_idx].ext_irq_subdevices; i++) {
- subdevice =
- (me_subdevice_t *)
- me4600_ext_irq_constructor(me4600_device->base.info.pci.
- reg_bases[2],
- me4600_device->base.irq,
- &me4600_device->ai_ctrl_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me4600_device);
- kfree(me4600_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me4600_device->base.slist,
- subdevice);
- }
-
- return (me_device_t *) me4600_device;
-}
-EXPORT_SYMBOL(me4600_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me4600_init(void)
-{
- PDEBUG("executed.\n");
-
-#ifndef BOSCH
- me4600_workqueue = create_singlethread_workqueue("me4600");
-#endif
- return 0;
-}
-
-static void __exit me4600_exit(void)
-{
- PDEBUG("executed.\n");
-
-#ifndef BOSCH
- flush_workqueue(me4600_workqueue);
- destroy_workqueue(me4600_workqueue);
-#endif
-}
-
-module_init(me4600_init);
-module_exit(me4600_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
- ("Guenter Gebhardt <g.gebhardt at meilhaus.de> & Krzysztof Gantzke <k.gantzke at meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for ME-46xx Devices");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-46xx Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me4600_device.h b/drivers/staging/meilhaus/me4600_device.h
deleted file mode 100644
index c755c57..0000000
--- a/drivers/staging/meilhaus/me4600_device.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * @file me4600_device.h
- *
- * @brief ME-4600 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_DEVICE_H
-#define _ME4600_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-4600 device capabilities.
- */
-typedef struct me4600_version {
- uint16_t device_id;
- unsigned int do_subdevices;
- unsigned int di_subdevices;
- unsigned int dio_subdevices;
- unsigned int ctr_subdevices;
- unsigned int ai_subdevices;
- unsigned int ai_channels;
- unsigned int ai_ranges;
- unsigned int ai_isolated;
- unsigned int ai_sh;
- unsigned int ao_subdevices;
- unsigned int ao_fifo; //How many devices have FIFO
- unsigned int ext_irq_subdevices;
-} me4600_version_t;
-
-/**
- * @brief ME-4600 device capabilities.
- */
-static me4600_version_t me4600_versions[] = {
- {PCI_DEVICE_ID_MEILHAUS_ME4610, 0, 0, 4, 3, 1, 16, 1, 0, 0, 0, 0, 1},
-
- {PCI_DEVICE_ID_MEILHAUS_ME4650, 0, 0, 4, 0, 1, 16, 4, 0, 0, 0, 0, 1},
-
- {PCI_DEVICE_ID_MEILHAUS_ME4660, 0, 0, 4, 3, 1, 16, 4, 0, 0, 2, 0, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME4660I, 1, 1, 2, 3, 1, 16, 4, 1, 0, 2, 0, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME4660S, 0, 0, 4, 3, 1, 16, 4, 0, 1, 2, 0, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME4660IS, 1, 1, 2, 3, 1, 16, 4, 1, 1, 2, 0, 1},
-
- {PCI_DEVICE_ID_MEILHAUS_ME4670, 0, 0, 4, 3, 1, 32, 4, 0, 0, 4, 0, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME4670I, 1, 1, 2, 3, 1, 32, 4, 1, 0, 4, 0, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME4670S, 0, 0, 4, 3, 1, 32, 4, 0, 1, 4, 0, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME4670IS, 1, 1, 2, 3, 1, 32, 4, 1, 1, 4, 0, 1},
-
- {PCI_DEVICE_ID_MEILHAUS_ME4680, 0, 0, 4, 3, 1, 32, 4, 0, 0, 4, 4, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME4680I, 1, 1, 2, 3, 1, 32, 4, 1, 0, 4, 4, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME4680S, 0, 0, 4, 3, 1, 32, 4, 0, 1, 4, 4, 1},
- {PCI_DEVICE_ID_MEILHAUS_ME4680IS, 1, 1, 2, 3, 1, 32, 4, 1, 1, 4, 4, 1},
-
- {0},
-};
-
-#define ME4600_DEVICE_VERSIONS (ARRAY_SIZE(me4600_versions) - 1) /**< Returns the number of entries in #me4600_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me4600_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me4600_versions.
- */
-static inline unsigned int me4600_versions_get_device_index(uint16_t device_id)
-{
- unsigned int i;
- for (i = 0; i < ME4600_DEVICE_VERSIONS; i++)
- if (me4600_versions[i].device_id == device_id)
- break;
- return i;
-}
-
-/**
- * @brief The ME-4600 device class structure.
- */
-typedef struct me4600_device {
- me_device_t base; /**< The Meilhaus device base class. */
-
- /* Child class attributes. */
- spinlock_t preload_reg_lock; /**< Guards the preload register of the anaolog output devices. */
- unsigned int preload_flags; /**< Used in conjunction with #preload_reg_lock. */
- spinlock_t dio_lock; /**< Locks the control register of the digital input/output subdevices. */
- spinlock_t ai_ctrl_lock; /**< Locks the control register of the analog input subdevice. */
- spinlock_t ctr_ctrl_reg_lock; /**< Locks the counter control register. */
- spinlock_t ctr_clk_src_reg_lock; /**< Not used on this device but needed for the me8254 subdevice constructor call. */
-} me4600_device_t;
-
-/**
- * @brief The ME-4600 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- * @param me_bosch_fw If set the device shall use the bosch firmware. (Only for special BOSCH build)
- *
- * @return On succes a new ME-4600 device instance. \n
- * NULL on error.
- */
-
-#ifdef BOSCH
-/**
- * @brief The ME-4600 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- * @param me_bosch_fw If set the device shall use the bosch firmware.
- *
- * @return On succes a new ME-4600 device instance. \n
- * NULL on error.
- */
-me_device_t *me4600_pci_constructor(struct pci_dev *pci_device, int me_bosch_fw)
- __attribute__ ((weak));
-#else //~BOSCH
-/**
- * @brief The ME-4600 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-4600 device instance. \n
- * NULL on error.
- */
-me_device_t *me4600_pci_constructor(struct pci_dev *pci_device)
- __attribute__ ((weak));
-#endif
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_di.c b/drivers/staging/meilhaus/me4600_di.c
deleted file mode 100644
index e107e50..0000000
--- a/drivers/staging/meilhaus/me4600_di.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/**
- * @file me4600_di.c
- *
- * @brief ME-4000 digital input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me4600_dio_reg.h"
-#include "me4600_di.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me4600_di_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me4600_di_subdevice_t *instance;
- uint32_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_di_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inl(instance->ctrl_reg);
- mode &= ~(ME4600_DIO_CTRL_BIT_MODE_2 | ME4600_DIO_CTRL_BIT_MODE_3); //0xFFF3
- outl(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- spin_unlock(instance->ctrl_reg_lock);
-
- outl(0, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->port_reg - instance->reg_base, 0);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_di_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- int err = ME_ERRNO_SUCCESS;
- me4600_di_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_di_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- switch (flags) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_BYTE:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
- } else {
- PERROR("Invalid port direction specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_di_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me4600_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_di_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- *value = inl(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = inl(instance->port_reg) & 0xFF;
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_di_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_di_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DI;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- PDEBUG("executed.\n");
- *caps = 0;
- return ME_ERRNO_SUCCESS;
-}
-
-me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base,
- spinlock_t *ctrl_reg_lock)
-{
- me4600_di_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me4600_di_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me4600_di_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Save the subdevice index */
- subdevice->port_reg = reg_base + ME4600_DIO_PORT_1_REG;
- subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me4600_di_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me4600_di_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me4600_di_io_single_read;
- subdevice->base.me_subdevice_query_number_channels =
- me4600_di_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me4600_di_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me4600_di_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me4600_di.h b/drivers/staging/meilhaus/me4600_di.h
deleted file mode 100644
index ec8b175..0000000
--- a/drivers/staging/meilhaus/me4600_di.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file me4600_di.h
- *
- * @brief ME-4000 digital input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_DI_H_
-#define _ME4600_DI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me4600_di_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
-
- unsigned long port_reg; /**< Register holding the port status. */
- unsigned long ctrl_reg; /**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me4600_di_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-4000 digital input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base,
- spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_dio.c b/drivers/staging/meilhaus/me4600_dio.c
deleted file mode 100644
index baa28ff..0000000
--- a/drivers/staging/meilhaus/me4600_dio.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/**
- * @file me4600_dio.c
- *
- * @brief ME-4000 digital input/output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me4600_dio_reg.h"
-#include "me4600_dio.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me4600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me4600_dio_subdevice_t *instance;
- uint32_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_dio_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- /* Set port to input mode */
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inl(instance->ctrl_reg);
- mode &=
- ~((ME4600_DIO_CTRL_BIT_MODE_0 | ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- outl(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- spin_unlock(instance->ctrl_reg_lock);
-
- outl(0, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->port_reg - instance->reg_base, 0);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_dio_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me4600_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t mode;
- uint32_t size =
- flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
- | ME_IO_SINGLE_CONFIG_DIO_WORD |
- ME_IO_SINGLE_CONFIG_DIO_DWORD);
- uint32_t mask;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inl(instance->ctrl_reg);
- switch (size) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_BYTE:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
- mode &=
- ~((ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
- mode &=
- ~((ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- mode |=
- ME4600_DIO_CTRL_BIT_MODE_0 << (instance->
- dio_idx * 2);
- } else if (single_config == ME_SINGLE_CONFIG_DIO_MUX32M) {
- mask =
- (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
- dio_idx *
- 2);
- mask |=
- ME4600_DIO_CTRL_BIT_FUNCTION_0 |
- ME4600_DIO_CTRL_BIT_FUNCTION_1;
- mask |=
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
- instance->dio_idx;
- mode &= ~mask;
-
- if (ref == ME_REF_DIO_FIFO_LOW) {
- mode |=
- (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2);
- mode |= ME4600_DIO_CTRL_BIT_FUNCTION_1;
- } else if (ref == ME_REF_DIO_FIFO_HIGH) {
- mode |=
- (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2);
- mode |= ME4600_DIO_CTRL_BIT_FUNCTION_1;
- mode |=
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
- instance->dio_idx;
- } else {
- PERROR
- ("Invalid port reference specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else if (single_config ==
- ME_SINGLE_CONFIG_DIO_DEMUX32) {
- mask =
- (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
- dio_idx *
- 2);
- mask |=
- ME4600_DIO_CTRL_BIT_FUNCTION_0 |
- ME4600_DIO_CTRL_BIT_FUNCTION_1;
- mask |=
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
- instance->dio_idx;
- mode &= ~mask;
-
- if (ref == ME_REF_DIO_FIFO_LOW) {
- mode |=
- (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2);
- mode |= ME4600_DIO_CTRL_BIT_FUNCTION_0;
- } else if (ref == ME_REF_DIO_FIFO_HIGH) {
- mode |=
- (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2);
- mode |= ME4600_DIO_CTRL_BIT_FUNCTION_0;
- mode |=
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
- instance->dio_idx;
- } else {
- PERROR
- ("Invalid port reference specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else if (single_config ==
- ME_SINGLE_CONFIG_DIO_BIT_PATTERN) {
- mask =
- (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
- dio_idx *
- 2);
- mask |=
- ME4600_DIO_CTRL_BIT_FUNCTION_0 |
- ME4600_DIO_CTRL_BIT_FUNCTION_1;
- mask |=
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
- instance->dio_idx;
- mode &= ~mask;
-
- if (ref == ME_REF_DIO_FIFO_LOW) {
- mode |=
- (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2);
- } else if (ref == ME_REF_DIO_FIFO_HIGH) {
- mode |=
- (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2);
- mode |=
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
- instance->dio_idx;
- } else {
- PERROR
- ("Invalid port reference specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR
- ("Invalid port configuration specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- if (!err) {
- outl(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_dio_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me4600_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- mode =
- inl(instance->
- ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- if ((mode ==
- (ME4600_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) || !mode) {
- *value =
- inl(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- mode =
- inl(instance->
- ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- if ((mode ==
- (ME4600_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) || !mode) {
- *value = inl(instance->port_reg) & 0xFF;
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_dio_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me4600_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t mode;
- uint32_t byte;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- mode =
- inl(instance->
- ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
-
- if (mode ==
- (ME4600_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) {
- byte = inl(instance->port_reg) & 0xFF;
-
- if (value)
- byte |= 0x1 << channel;
- else
- byte &= ~(0x1 << channel);
-
- outl(byte, instance->port_reg);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- mode =
- inl(instance->
- ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
-
- if (mode ==
- (ME4600_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) {
- outl(value, instance->port_reg);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_dio_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_dio_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DIO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_dio_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_DIO_DIR_BYTE;
- return ME_ERRNO_SUCCESS;
-}
-
-me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base,
- unsigned int dio_idx,
- spinlock_t *ctrl_reg_lock)
-{
- me4600_dio_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me4600_dio_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me4600_dio_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Save digital i/o index */
- subdevice->dio_idx = dio_idx;
-
- /* Save the subdevice index */
- subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
- subdevice->port_reg = reg_base + ME4600_DIO_PORT_REG + (dio_idx * 4);
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me4600_dio_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me4600_dio_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me4600_dio_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me4600_dio_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me4600_dio_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me4600_dio_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me4600_dio_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me4600_dio.h b/drivers/staging/meilhaus/me4600_dio.h
deleted file mode 100644
index 4625ba9..0000000
--- a/drivers/staging/meilhaus/me4600_dio.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @file me4600_dio.h
- *
- * @brief ME-4000 digital input/output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_DIO_H_
-#define _ME4600_DIO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me4600_dio_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
- unsigned int dio_idx; /**< The index of the digital i/o on the device. */
-
- /* Registers */
- unsigned long port_reg; /**< Register holding the port status. */
- unsigned long ctrl_reg; /**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me4600_dio_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-4000 digital input/ouput subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param dio_idx The index of the digital i/o port on the device.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base,
- unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_dio_reg.h b/drivers/staging/meilhaus/me4600_dio_reg.h
deleted file mode 100644
index 7a4016a..0000000
--- a/drivers/staging/meilhaus/me4600_dio_reg.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file me4600_dio_reg.h
- *
- * @brief ME-4000 digital input/output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_DIO_REG_H_
-#define _ME4600_DIO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME4600_DIO_PORT_0_REG 0xA0 /**< Port 0 register. */
-#define ME4600_DIO_PORT_1_REG 0xA4 /**< Port 1 register. */
-#define ME4600_DIO_PORT_2_REG 0xA8 /**< Port 2 register. */
-#define ME4600_DIO_PORT_3_REG 0xAC /**< Port 3 register. */
-
-#define ME4600_DIO_DIR_REG 0xB0 /**< Direction register. */
-#define ME4600_DIO_PORT_REG ME4600_DIO_PORT_0_REG /**< Base for port's register. */
-
-#define ME4600_DIO_CTRL_REG 0xB8 /**< Control register. */
-/** Port A - DO */
-#define ME4600_DIO_CTRL_BIT_MODE_0 0x0001
-#define ME4600_DIO_CTRL_BIT_MODE_1 0x0002
-/** Port B - DI */
-#define ME4600_DIO_CTRL_BIT_MODE_2 0x0004
-#define ME4600_DIO_CTRL_BIT_MODE_3 0x0008
-/** Port C - DIO */
-#define ME4600_DIO_CTRL_BIT_MODE_4 0x0010
-#define ME4600_DIO_CTRL_BIT_MODE_5 0x0020
-/** Port D - DIO */
-#define ME4600_DIO_CTRL_BIT_MODE_6 0x0040
-#define ME4600_DIO_CTRL_BIT_MODE_7 0x0080
-
-#define ME4600_DIO_CTRL_BIT_FUNCTION_0 0x0100
-#define ME4600_DIO_CTRL_BIT_FUNCTION_1 0x0200
-
-#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 0x0400
-#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_1 0x0800
-#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_2 0x1000
-#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_3 0x2000
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_do.c b/drivers/staging/meilhaus/me4600_do.c
deleted file mode 100644
index 39510f3..0000000
--- a/drivers/staging/meilhaus/me4600_do.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/**
- * @file me4600_do.c
- *
- * @brief ME-4000 digital output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me4600_dio_reg.h"
-#include "me4600_do.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me4600_do_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me4600_do_subdevice_t *instance;
- uint32_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_do_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- /* Set port to output mode */
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inl(instance->ctrl_reg);
- mode &= ~ME4600_DIO_CTRL_BIT_MODE_1; //0xFFFD
- mode |= ME4600_DIO_CTRL_BIT_MODE_0; //0x1
- outl(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- spin_unlock(instance->ctrl_reg_lock);
-
- outl(0, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->port_reg - instance->reg_base, 0);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_do_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me4600_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t mode;
- int size =
- flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
- | ME_IO_SINGLE_CONFIG_DIO_WORD |
- ME_IO_SINGLE_CONFIG_DIO_DWORD);
-
- PDEBUG("executed.\n");
-
- instance = (me4600_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inl(instance->ctrl_reg);
-
- switch (size) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_BYTE:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
- mode &= ~(ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1);
- mode |= (ME4600_DIO_CTRL_BIT_MODE_0);
- } else if (single_config == ME_SINGLE_CONFIG_DIO_MUX32M) {
- mode &= ~(ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1 |
- ME4600_DIO_CTRL_BIT_FUNCTION_0 |
- ME4600_DIO_CTRL_BIT_FUNCTION_1 |
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
-
- if (ref == ME_REF_DIO_FIFO_LOW) {
- mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1 |
- ME4600_DIO_CTRL_BIT_FUNCTION_1);
- } else if (ref == ME_REF_DIO_FIFO_HIGH) {
- mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1 |
- ME4600_DIO_CTRL_BIT_FUNCTION_1
- |
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
- } else {
- PERROR
- ("Invalid port reference specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else if (single_config ==
- ME_SINGLE_CONFIG_DIO_DEMUX32) {
- mode &=
- ~(ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1 |
- ME4600_DIO_CTRL_BIT_FUNCTION_0 |
- ME4600_DIO_CTRL_BIT_FUNCTION_1 |
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
-
- if (ref == ME_REF_DIO_FIFO_LOW) {
- mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1 |
- ME4600_DIO_CTRL_BIT_FUNCTION_0);
- } else if (ref == ME_REF_DIO_FIFO_HIGH) {
- mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1 |
- ME4600_DIO_CTRL_BIT_FUNCTION_0
- |
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
- } else {
- PERROR
- ("Invalid port reference specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else if (single_config ==
- ME_SINGLE_CONFIG_DIO_BIT_PATTERN) {
- mode &=
- ~(ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1 |
- ME4600_DIO_CTRL_BIT_FUNCTION_0 |
- ME4600_DIO_CTRL_BIT_FUNCTION_1 |
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
-
- if (ref == ME_REF_DIO_FIFO_LOW) {
- mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1);
- } else if (ref == ME_REF_DIO_FIFO_HIGH) {
- mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1 |
- ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
- } else {
- PERROR
- ("Invalid port reference specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid port direction specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- if (!err) {
- outl(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_do_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me4600_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode =
- inl(instance->
- ctrl_reg) & (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1);
-
- if (mode == ME4600_DIO_CTRL_BIT_MODE_0) {
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- *value =
- inl(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = inl(instance->port_reg) & 0xFF;
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- } else {
- PERROR("Port not in output mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_do_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me4600_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t byte;
- uint32_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode =
- inl(instance->
- ctrl_reg) & (ME4600_DIO_CTRL_BIT_MODE_0 |
- ME4600_DIO_CTRL_BIT_MODE_1);
-
- if (mode == ME4600_DIO_CTRL_BIT_MODE_0) {
- switch (flags) {
-
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- byte = inl(instance->port_reg) & 0xFF;
-
- if (value)
- byte |= 0x1 << channel;
- else
- byte &= ~(0x1 << channel);
-
- outl(byte, instance->port_reg);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- outl(value, instance->port_reg);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- } else {
- PERROR("Port not in output mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_do_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_do_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- PDEBUG("executed.\n");
- *caps = 0;
- return ME_ERRNO_SUCCESS;
-}
-
-me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base,
- spinlock_t *ctrl_reg_lock)
-{
- me4600_do_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me4600_do_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me4600_do_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Save the subdevice index */
- subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
- subdevice->port_reg = reg_base + ME4600_DIO_PORT_0_REG;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me4600_do_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me4600_do_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me4600_do_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me4600_do_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me4600_do_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me4600_do_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me4600_do_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me4600_do.h b/drivers/staging/meilhaus/me4600_do.h
deleted file mode 100644
index e838564..0000000
--- a/drivers/staging/meilhaus/me4600_do.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * @file me4600_do.h
- *
- * @brief ME-4000 digital output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_DO_H_
-#define _ME4600_DO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me4600_do_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
-
- unsigned long port_reg; /**< Register holding the port status. */
- unsigned long ctrl_reg; /**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me4600_do_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-4000 digital output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base,
- spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_ext_irq.c b/drivers/staging/meilhaus/me4600_ext_irq.c
deleted file mode 100644
index cfb4adb..0000000
--- a/drivers/staging/meilhaus/me4600_ext_irq.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/**
- * @file me4600_ext_irq.c
- *
- * @brief ME-4000 external interrupt subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "meids.h"
-#include "me4600_reg.h"
-#include "me4600_ai_reg.h"
-#include "me4600_ext_irq_reg.h"
-#include "me4600_ext_irq.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me4600_ext_irq_io_irq_start(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int irq_source,
- int irq_edge, int irq_arg, int flags)
-{
- me4600_ext_irq_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long cpu_flags;
- uint32_t tmp;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ext_irq_subdevice_t *) subdevice;
-
- if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((irq_edge != ME_IRQ_EDGE_RISING)
- && (irq_edge != ME_IRQ_EDGE_FALLING)
- && (irq_edge != ME_IRQ_EDGE_ANY)
- ) {
- PERROR("Invalid irq edge specified.\n");
- return ME_ERRNO_INVALID_IRQ_EDGE;
- }
-
- if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
- PERROR("Invalid irq source specified.\n");
- return ME_ERRNO_INVALID_IRQ_SOURCE;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- tmp = 0x0; //inl(instance->ext_irq_config_reg);
-
- if (irq_edge == ME_IRQ_EDGE_RISING) {
- //tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK;
- //tmp |= ME4600_EXT_IRQ_CONFIG_MASK_RISING;
- } else if (irq_edge == ME_IRQ_EDGE_FALLING) {
- //tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK;
- //tmp |= ME4600_EXT_IRQ_CONFIG_MASK_FALLING;
- tmp = ME4600_EXT_IRQ_CONFIG_MASK_FALLING;
- } else if (irq_edge == ME_IRQ_EDGE_ANY) {
- //tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK;
- //tmp |= ME4600_EXT_IRQ_CONFIG_MASK_ANY;
- tmp = ME4600_EXT_IRQ_CONFIG_MASK_ANY;
- }
-
- outl(tmp, instance->ext_irq_config_reg);
- PDEBUG_REG("ext_irq_config_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ext_irq_config_reg - instance->reg_base, tmp);
-
- spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
- tmp = inl(instance->ctrl_reg);
- tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
- tmp |= ME4600_AI_CTRL_BIT_EX_IRQ;
- outl(tmp, instance->ctrl_reg);
- spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
- instance->rised = 0;
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ext_irq_io_irq_wait(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *irq_count,
- int *value, int time_out, int flags)
-{
- me4600_ext_irq_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- long t = 0;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ext_irq_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (time_out < 0) {
- PERROR("Invalid time_out specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- t = (time_out * HZ) / 1000;
-
- if (t == 0)
- t = 1;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (instance->rised <= 0) {
- instance->rised = 0;
- if (time_out) {
- t = wait_event_interruptible_timeout(instance->
- wait_queue,
- (instance->rised !=
- 0), t);
-
- if (t == 0) {
- PERROR
- ("Wait on external interrupt timed out.\n");
- err = ME_ERRNO_TIMEOUT;
- }
- } else {
- wait_event_interruptible(instance->wait_queue,
- (instance->rised != 0));
- }
-
- if (instance->rised < 0) {
- PERROR("Wait on interrupt aborted by user.\n");
- err = ME_ERRNO_CANCELLED;
- }
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on external interrupt aborted by signal.\n");
- err = ME_ERRNO_SIGNAL;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- instance->rised = 0;
- *irq_count = instance->count;
- *value = instance->value;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ext_irq_io_irq_stop(me_subdevice_t *subdevice,
- struct file *filep,
- int channel, int flags)
-{
- me4600_ext_irq_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long cpu_flags;
- uint32_t tmp;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ext_irq_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
- tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_regv outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- spin_unlock(instance->ctrl_reg_lock);
- instance->rised = -1;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me4600_ext_irq_io_reset_subdevice(me_subdevice_t *subdevice,
- struct file *filep, int flags)
-{
- me4600_ext_irq_subdevice_t *instance;
- unsigned long cpu_flags;
- uint32_t tmp;
-
- PDEBUG("executed.\n");
-
- instance = (me4600_ext_irq_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- spin_lock(instance->ctrl_reg_lock);
- tmp = inl(instance->ctrl_reg);
- tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
- outl(tmp, instance->ctrl_reg);
- PDEBUG_REG("ctrl_regv outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, tmp);
- spin_unlock(instance->ctrl_reg_lock);
- instance->rised = -1;
- instance->count = 0;
- outl(ME4600_EXT_IRQ_CONFIG_MASK_ANY, instance->ext_irq_config_reg);
- PDEBUG_REG("ext_irq_config_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ext_irq_config_reg - instance->reg_base,
- ME4600_EXT_IRQ_CONFIG_MASK_ANY);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static void me4600_ext_irq_destructor(struct me_subdevice *subdevice)
-{
- me4600_ext_irq_subdevice_t *instance;
-
- PDEBUG("executed.\n");
- instance = (me4600_ext_irq_subdevice_t *) subdevice;
- me_subdevice_deinit(&instance->base);
- free_irq(instance->irq, instance);
- kfree(instance);
-}
-
-static int me4600_ext_irq_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 1;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ext_irq_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_EXT_IRQ;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps =
- ME_CAPS_EXT_IRQ_EDGE_RISING | ME_CAPS_EXT_IRQ_EDGE_FALLING |
- ME_CAPS_EXT_IRQ_EDGE_ANY;
- return ME_ERRNO_SUCCESS;
-}
-
-static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id)
-{
- me4600_ext_irq_subdevice_t *instance;
- uint32_t ctrl;
- uint32_t irq_status;
-
- instance = (me4600_ext_irq_subdevice_t *) dev_id;
-
- if (irq != instance->irq) {
- PERROR("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- irq_status = inl(instance->irq_status_reg);
- if (!(irq_status & ME4600_IRQ_STATUS_BIT_EX)) {
- PINFO("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n",
- jiffies, __func__, irq_status);
- return IRQ_NONE;
- }
-
- PDEBUG("executed.\n");
-
- spin_lock(&instance->subdevice_lock);
- instance->rised = 1;
- instance->value = inl(instance->ext_irq_value_reg);
- instance->count++;
-
- spin_lock(instance->ctrl_reg_lock);
- ctrl = inl(instance->ctrl_reg);
- ctrl |= ME4600_AI_CTRL_BIT_EX_IRQ_RESET;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- ctrl &= ~ME4600_AI_CTRL_BIT_EX_IRQ_RESET;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock(instance->ctrl_reg_lock);
-
- spin_unlock(&instance->subdevice_lock);
- wake_up_interruptible_all(&instance->wait_queue);
-
- return IRQ_HANDLED;
-}
-
-me4600_ext_irq_subdevice_t *me4600_ext_irq_constructor(uint32_t reg_base,
- int irq,
- spinlock_t *
- ctrl_reg_lock)
-{
- me4600_ext_irq_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me4600_ext_irq_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me4600_ext_irq_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Initialize wait queue */
- init_waitqueue_head(&subdevice->wait_queue);
-
- /* Register interrupt */
- subdevice->irq = irq;
-
- if (request_irq(subdevice->irq, me4600_ext_irq_isr,
- IRQF_DISABLED | IRQF_SHARED,
- ME4600_NAME, subdevice)) {
- PERROR("Cannot register interrupt.\n");
- kfree(subdevice);
- return NULL;
- }
- PINFO("Registered irq=%d.\n", subdevice->irq);
-
- /* Initialize registers */
- subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
- subdevice->ctrl_reg = reg_base + ME4600_AI_CTRL_REG;
- subdevice->ext_irq_config_reg = reg_base + ME4600_EXT_IRQ_CONFIG_REG;
- subdevice->ext_irq_value_reg = reg_base + ME4600_EXT_IRQ_VALUE_REG;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Override base class methods. */
- subdevice->base.me_subdevice_destructor = me4600_ext_irq_destructor;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me4600_ext_irq_io_reset_subdevice;
- subdevice->base.me_subdevice_io_irq_start = me4600_ext_irq_io_irq_start;
- subdevice->base.me_subdevice_io_irq_wait = me4600_ext_irq_io_irq_wait;
- subdevice->base.me_subdevice_io_irq_stop = me4600_ext_irq_io_irq_stop;
- subdevice->base.me_subdevice_query_number_channels =
- me4600_ext_irq_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me4600_ext_irq_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me4600_ext_irq_query_subdevice_caps;
-
- subdevice->rised = 0;
- subdevice->count = 0;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me4600_ext_irq.h b/drivers/staging/meilhaus/me4600_ext_irq.h
deleted file mode 100644
index 3c7b27f..0000000
--- a/drivers/staging/meilhaus/me4600_ext_irq.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * @file me4600_ext_irq.h
- *
- * @brief Meilhaus ME-4000 external interrupt subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_EXT_IRQ_H_
-#define _ME4600_EXT_IRQ_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The subdevice class.
- */
-typedef struct me4600_ext_irq_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
-
- wait_queue_head_t wait_queue;
-
- int irq;
-
- int rised;
- int value;
- int count;
-
- unsigned long ctrl_reg;
- unsigned long irq_status_reg;
- unsigned long ext_irq_config_reg;
- unsigned long ext_irq_value_reg;
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me4600_ext_irq_subdevice_t;
-
-/**
- * @brief The constructor to generate a external interrupt subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param irq The interrupt number assigned by the PCI BIOS.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_ext_irq_subdevice_t *me4600_ext_irq_constructor(uint32_t reg_base,
- int irq,
- spinlock_t *
- ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_ext_irq_reg.h b/drivers/staging/meilhaus/me4600_ext_irq_reg.h
deleted file mode 100644
index 898e1e7..0000000
--- a/drivers/staging/meilhaus/me4600_ext_irq_reg.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file me4600_ext_irq_reg.h
- *
- * @brief ME-4000 external interrupt subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_EXT_IRQ_REG_H_
-#define _ME4600_EXT_IRQ_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME4600_EXT_IRQ_CONFIG_REG 0xCC // R/_
-#define ME4600_EXT_IRQ_VALUE_REG 0xD0 // R/_
-
-#define ME4600_EXT_IRQ_CONFIG_MASK_RISING 0x0
-#define ME4600_EXT_IRQ_CONFIG_MASK_FALLING 0x1
-#define ME4600_EXT_IRQ_CONFIG_MASK_ANY 0x3
-#define ME4600_EXT_IRQ_CONFIG_MASK 0x3
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_reg.h b/drivers/staging/meilhaus/me4600_reg.h
deleted file mode 100644
index ae152bb..0000000
--- a/drivers/staging/meilhaus/me4600_reg.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file me4600_reg.h
- *
- * @brief ME-4000 register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME4600_REG_H_
-#define _ME4600_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME4600_IRQ_STATUS_REG 0x9C // R/_
-
-#define ME4600_IRQ_STATUS_BIT_EX 0x01
-#define ME4600_IRQ_STATUS_BIT_LE 0x02
-#define ME4600_IRQ_STATUS_BIT_AI_HF 0x04
-#define ME4600_IRQ_STATUS_BIT_AO_0_HF 0x08
-#define ME4600_IRQ_STATUS_BIT_AO_1_HF 0x10
-#define ME4600_IRQ_STATUS_BIT_AO_2_HF 0x20
-#define ME4600_IRQ_STATUS_BIT_AO_3_HF 0x40
-#define ME4600_IRQ_STATUS_BIT_SC 0x80
-
-#define ME4600_IRQ_STATUS_BIT_AO_HF ME4600_IRQ_STATUS_BIT_AO_0_HF
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me6000_ao.c b/drivers/staging/meilhaus/me6000_ao.c
deleted file mode 100644
index 66652dc..0000000
--- a/drivers/staging/meilhaus/me6000_ao.c
+++ /dev/null
@@ -1,3709 +0,0 @@
-/**
- * @file me6000_ao.c
- *
- * @brief ME-6000 analog output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/* Includes
- */
-#include <linux/version.h>
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include <linux/workqueue.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "meids.h"
-#include "me6000_reg.h"
-#include "me6000_ao_reg.h"
-#include "me6000_ao.h"
-
-/* Defines
- */
-
-static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice,
- int unit,
- int *min,
- int *max, int *maxdata, int *range);
-
-static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice,
- int unit, int *count);
-
-static int me6000_ao_query_range_info(me_subdevice_t *subdevice,
- int range,
- int *unit,
- int *min, int *max, int *maxdata);
-
-static int me6000_ao_query_timer(me_subdevice_t *subdevice,
- int timer,
- int *base_frequency,
- long long *min_ticks, long long *max_ticks);
-
-static int me6000_ao_query_number_channels(me_subdevice_t *subdevice,
- int *number);
-
-static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype);
-
-static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps);
-
-static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
- int cap, int *args, int count);
-
-/** Remove subdevice. */
-static void me6000_ao_destructor(struct me_subdevice *subdevice);
-
-/** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'. */
-static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice,
- struct file *filep, int flags);
-
-/** Set output as single */
-static int me6000_ao_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags);
-
-/** Pass to user actual value of output. */
-static int me6000_ao_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags);
-
-/** Write to output requed value. */
-static int me6000_ao_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags);
-
-/** Set output as streamed device. */
-static int me6000_ao_io_stream_config(me_subdevice_t *subdevice,
- struct file *filep,
- meIOStreamConfig_t *config_list,
- int count,
- meIOStreamTrigger_t *trigger,
- int fifo_irq_threshold, int flags);
-
-/** Wait for / Check empty space in buffer. */
-static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice,
- struct file *filep,
- int time_out, int *count, int flags);
-
-/** Start streaming. */
-static int me6000_ao_io_stream_start(me_subdevice_t *subdevice,
- struct file *filep,
- int start_mode, int time_out, int flags);
-
-/** Check actual state. / Wait for end. */
-static int me6000_ao_io_stream_status(me_subdevice_t *subdevice,
- struct file *filep,
- int wait,
- int *status, int *values, int flags);
-
-/** Stop streaming. */
-static int me6000_ao_io_stream_stop(me_subdevice_t *subdevice,
- struct file *filep,
- int stop_mode, int flags);
-
-/** Write datas to buffor. */
-static int me6000_ao_io_stream_write(me_subdevice_t *subdevice,
- struct file *filep,
- int write_mode,
- int *values, int *count, int flags);
-
-/** Interrupt handler. Copy from buffer to FIFO. */
-static irqreturn_t me6000_ao_isr(int irq, void *dev_id);
-
-/** Copy data from circular buffer to fifo (fast) in wraparound mode. */
-inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count,
- int start_pos);
-
-/** Copy data from circular buffer to fifo (fast).*/
-inline int ao_write_data(me6000_ao_subdevice_t *instance, int count,
- int start_pos);
-
-/** Copy data from circular buffer to fifo (slow).*/
-inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count,
- int start_pos);
-
-/** Copy data from user space to circular buffer. */
-inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count,
- int *user_values);
-
-/** Stop presentation. Preserve FIFOs. */
-inline int ao_stop_immediately(me6000_ao_subdevice_t *instance);
-
-/** Function for checking timeout in non-blocking mode. */
-static void me6000_ao_work_control_task(struct work_struct *work);
-
-/* Functions
- */
-
-static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice,
- struct file *filep, int flags)
-{
- me6000_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t tmp;
- uint32_t ctrl;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- instance->status = ao_status_none;
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
- instance->timeout.delay = 0;
- instance->timeout.start_time = jiffies;
-
- //Stop state machine.
- err = ao_stop_immediately(instance);
-
- //Remove from synchronous start.
- spin_lock(instance->preload_reg_lock);
- tmp = inl(instance->preload_reg);
- tmp &=
- ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->
- ao_idx);
- outl(tmp, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->preload_reg - instance->reg_base, tmp);
- *instance->preload_flags &=
- ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->
- ao_idx);
-
- //Reset triggering flag
- *instance->triggering_flags &= ~(0x1 << instance->ao_idx);
- spin_unlock(instance->preload_reg_lock);
-
- if (instance->fifo) {
- //Set single mode, dissable FIFO, dissable external trigger, block interrupt.
- ctrl = ME6000_AO_MODE_SINGLE;
-
- //Block ISM.
- ctrl |=
- (ME6000_AO_CTRL_BIT_STOP |
- ME6000_AO_CTRL_BIT_IMMEDIATE_STOP);
-
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- //Set speed
- outl(ME6000_AO_MIN_CHAN_TICKS - 1, instance->timer_reg);
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
- }
-
- instance->hardware_stop_delay = HZ / 10; //100ms
-
- //Set output to 0V
- outl(0x8000, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->single_reg - instance->reg_base, 0x8000);
-
- instance->circ_buf.head = 0;
- instance->circ_buf.tail = 0;
- instance->preloaded_count = 0;
- instance->data_count = 0;
- instance->single_value = 0x8000;
- instance->single_value_in_fifo = 0x8000;
-
- //Set status to signal that device is unconfigured.
- instance->status = ao_status_none;
- //Signal reset if user is on wait.
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_ao_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me6000_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t ctrl;
- uint32_t sync;
- unsigned long cpu_flags;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. ID=%d\n", instance->ao_idx);
-
- // Checking parameters
- if (flags) {
- PERROR
- ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (instance->fifo) { //Stream hardware (with or without fifo)
- if ((trig_edge == ME_TRIG_TYPE_SW)
- && (trig_edge != ME_TRIG_EDGE_NONE)) {
- PERROR
- ("Invalid trigger edge. Software trigger has not edge.\n");
- return ME_ERRNO_INVALID_TRIG_EDGE;
- }
-
- if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) {
- switch (trig_edge) {
- case ME_TRIG_EDGE_ANY:
- case ME_TRIG_EDGE_RISING:
- case ME_TRIG_EDGE_FALLING:
- break;
-
- default:
- PERROR("Invalid trigger edge.\n");
- return ME_ERRNO_INVALID_TRIG_EDGE;
- }
- }
-
- if ((trig_type != ME_TRIG_TYPE_SW)
- && (trig_type != ME_TRIG_TYPE_EXT_DIGITAL)) {
- PERROR
- ("Invalid trigger type. Trigger must be software or digital.\n");
- return ME_ERRNO_INVALID_TRIG_TYPE;
- }
- } else { //Single
- if (trig_edge != ME_TRIG_EDGE_NONE) {
- PERROR
- ("Invalid trigger edge. Single output trigger hasn't own edge.\n");
- return ME_ERRNO_INVALID_TRIG_EDGE;
- }
-
- if (trig_type != ME_TRIG_TYPE_SW) {
- PERROR
- ("Invalid trigger type. Trigger must be software.\n");
- return ME_ERRNO_INVALID_TRIG_TYPE;
- }
-
- }
-
- if ((trig_chan != ME_TRIG_CHAN_DEFAULT)
- && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) {
- PERROR("Invalid trigger channel specified.\n");
- return ME_ERRNO_INVALID_TRIG_CHAN;
- }
-/*
- if ((trig_type == ME_TRIG_TYPE_EXT_DIGITAL) && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS))
- {
- PERROR("Invalid trigger channel specified. Must be synchronous when digital is choose.\n");
- return ME_ERRNO_INVALID_TRIG_CHAN;
- }
-*/
- if (ref != ME_REF_AO_GROUND) {
- PERROR
- ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n");
- return ME_ERRNO_INVALID_REF;
- }
-
- if (single_config != 0) {
- PERROR
- ("Invalid single config specified. Only one range for anlog outputs is available.\n");
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
-
- if (channel != 0) {
- PERROR
- ("Invalid channel number specified. Analog output have only one channel.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- //Subdevice running in stream mode!
- if ((instance->status >= ao_status_stream_run_wait)
- && (instance->status < ao_status_stream_end)) {
- PERROR("Subdevice is busy.\n");
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
-/// @note For single all calls (config and write) are erasing previous state!
-
- instance->status = ao_status_none;
-
- // Correct single mirrors
- instance->single_value_in_fifo = instance->single_value;
-
- //Stop device
- err = ao_stop_immediately(instance);
- if (err) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
-
- if (instance->fifo) { // Set control register.
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- // Set stop bit. Stop streaming mode (If running.).
- ctrl = inl(instance->ctrl_reg);
- //Reset all bits.
- ctrl =
- ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP;
- if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) {
- PINFO("External digital trigger.\n");
-
- if (trig_edge == ME_TRIG_EDGE_ANY) {
-// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
- instance->ctrl_trg =
- ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
- ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
- } else if (trig_edge == ME_TRIG_EDGE_FALLING) {
-// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
- instance->ctrl_trg =
- ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
- } else if (trig_edge == ME_TRIG_EDGE_RISING) {
- instance->ctrl_trg = 0x0;
- }
- } else if (trig_type == ME_TRIG_TYPE_SW) {
- PDEBUG("SOFTWARE TRIGGER\n");
- instance->ctrl_trg = 0x0;
- }
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- } else {
- PDEBUG("SOFTWARE TRIGGER\n");
- }
-
- // Set preload/synchronization register.
- spin_lock(instance->preload_reg_lock);
-
- if (trig_type == ME_TRIG_TYPE_SW) {
- *instance->preload_flags &=
- ~(ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx);
- } else //if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL)
- {
- *instance->preload_flags |=
- ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx;
- }
-
- if (trig_chan == ME_TRIG_CHAN_DEFAULT) {
- *instance->preload_flags &=
- ~(ME6000_AO_SYNC_HOLD << instance->ao_idx);
- } else //if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS)
- {
- *instance->preload_flags |=
- ME6000_AO_SYNC_HOLD << instance->ao_idx;
- }
-
- //Reset hardware register
- sync = inl(instance->preload_reg);
- PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->preload_reg - instance->reg_base, sync);
- sync &= ~(ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx);
- sync |= ME6000_AO_SYNC_HOLD << instance->ao_idx;
-
- //Output configured in default mode (safe one)
- outl(sync, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->preload_reg - instance->reg_base, sync);
- spin_unlock(instance->preload_reg_lock);
-
- instance->status = ao_status_single_configured;
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_ao_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me6000_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- unsigned long j;
- unsigned long delay = 0;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags & ~ME_IO_SINGLE_NONBLOCKING) {
- PERROR("Invalid flag specified. %d\n", flags);
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((instance->status >= ao_status_stream_configured)
- && (instance->status <= ao_status_stream_end)) {
- PERROR("Subdevice not configured to work in single mode!\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-
- if (channel != 0) {
- PERROR("Invalid channel number specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- ME_SUBDEVICE_ENTER;
- if ((!flags) && (instance->status == ao_status_single_run_wait)) { //Blocking mode. Wait for trigger.
- if (time_out) {
- delay = (time_out * HZ) / 1000;
- if (delay == 0)
- delay = 1;
- }
-
- j = jiffies;
-
- //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
- wait_event_interruptible_timeout(instance->wait_queue,
- (instance->status !=
- ao_status_single_run_wait),
- (delay) ? delay : LONG_MAX);
-
- if (instance->status == ao_status_none) {
- PDEBUG("Single canceled.\n");
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on start of state machine interrupted.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- }
-
- if ((delay) && ((jiffies - j) >= delay)) {
- PDEBUG("Timeout reached.\n");
- err = ME_ERRNO_TIMEOUT;
- }
-
- *value =
- (!err) ? instance->single_value_in_fifo : instance->
- single_value;
- } else { //Non-blocking mode
- //Read value
- *value = instance->single_value;
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_ao_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me6000_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long cpu_flags;
- unsigned long j;
- unsigned long delay = 0;
-
- uint32_t sync_mask;
- uint32_t mode;
-
- uint32_t tmp;
-
-/// Workaround for mix-mode - begin
- uint32_t ctrl = 0x0;
- uint32_t status;
-/// Workaround for mix-mode - end
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags &
- ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS |
- ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((instance->status == ao_status_none)
- || (instance->status > ao_status_single_end)) {
- PERROR("Subdevice not configured to work in single mode!\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-
- if (channel != 0) {
- PERROR("Invalid channel number specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (value & ~ME6000_AO_MAX_DATA) {
- PERROR("Invalid value provided.\n");
- return ME_ERRNO_VALUE_OUT_OF_RANGE;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- ME_SUBDEVICE_ENTER;
-
-/// @note For single all calls (config and write) are erasing previous state!
-
- //Cancel control task
- PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
-
- // Correct single mirrors
- instance->single_value_in_fifo = instance->single_value;
-
- //Stop device
- err = ao_stop_immediately(instance);
- if (err) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
-
- if (time_out) {
- delay = (time_out * HZ) / 1000;
-
- if (delay == 0)
- delay = 1;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
- instance->single_value_in_fifo = value;
-
- if (instance->fifo) {
- ctrl = inl(instance->ctrl_reg);
- }
-
- if (instance->fifo & ME6000_AO_HAS_FIFO) { /// Workaround for mix-mode - begin
- //Set speed
- outl(ME6000_AO_MIN_CHAN_TICKS - 1, instance->timer_reg);
- PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->timer_reg - instance->reg_base,
- (int)ME6000_AO_MIN_CHAN_TICKS);
- instance->hardware_stop_delay = HZ / 10; //100ms
-
- status = inl(instance->status_reg);
-
- //Set the continous mode.
- ctrl &= ~ME6000_AO_CTRL_MODE_MASK;
- ctrl |= ME6000_AO_MODE_CONTINUOUS;
-
- //Prepare FIFO
- if (!(ctrl & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO wasn't enabeled. Do it.
- PINFO("Enableing FIFO.\n");
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
- } else { //Check if FIFO is empty
- if (status & ME6000_AO_STATUS_BIT_EF) { //FIFO not empty
- PINFO("Reseting FIFO.\n");
- ctrl &=
- ~(ME6000_AO_CTRL_BIT_ENABLE_FIFO |
- ME6000_AO_CTRL_BIT_ENABLE_IRQ);
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg -
- instance->reg_base, ctrl);
-
- ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
- } else { //FIFO empty, only interrupt needs to be disabled!
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- }
- }
-
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
-
- //Write output - 1 value to FIFO
- if (instance->ao_idx & 0x1) {
- outl(value <<= 16, instance->fifo_reg);
- PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->fifo_reg - instance->reg_base,
- value <<= 16);
- } else {
- outl(value, instance->fifo_reg);
- PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->fifo_reg - instance->reg_base,
- value);
- }
- /// Workaround for mix-mode - end
- } else { //No FIFO - always in single mode
- //Write value
- PDEBUG("Write value\n");
- outl(value, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base, value);
- }
-
- mode = *instance->preload_flags >> instance->ao_idx;
- mode &= (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG);
-
- PINFO("Triggering mode: 0x%08x\n", mode);
-
- spin_lock(instance->preload_reg_lock);
- sync_mask = inl(instance->preload_reg);
- PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->preload_reg - instance->reg_base, sync_mask);
- switch (mode) {
- case 0: //0x00000000: Individual software
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
- if (instance->fifo & ME6000_AO_HAS_FIFO) { // FIFO - Continous mode
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
- if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode.
- sync_mask &=
- ~((ME6000_AO_SYNC_EXT_TRIG |
- ME6000_AO_SYNC_HOLD) << instance->
- ao_idx);
-
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG
- ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- } else { // No FIFO - Single mode: In this case resetting 'ME6000_AO_SYNC_HOLD' will trigger output.
- 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.
- sync_mask &=
- ~(ME6000_AO_SYNC_EXT_TRIG << instance->
- ao_idx);
- sync_mask |=
- ME6000_AO_SYNC_HOLD << instance->ao_idx;
-
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG
- ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- }
- instance->single_value = value;
- break;
-
- case ME6000_AO_SYNC_EXT_TRIG: //0x00010000: Individual hardware
- PDEBUG("DIGITAL TRIGGER\n");
- ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
- if (instance->fifo & ME6000_AO_HAS_FIFO) { // FIFO - Continous mode
- if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode.
- sync_mask &=
- ~((ME6000_AO_SYNC_EXT_TRIG |
- ME6000_AO_SYNC_HOLD) << instance->
- ao_idx);
-
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG
- ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- } else { // No FIFO - Single mode
- 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
- sync_mask &=
- ~(ME6000_AO_SYNC_EXT_TRIG << instance->
- ao_idx);
- sync_mask |=
- ME6000_AO_SYNC_HOLD << instance->ao_idx;
-
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG
- ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- }
- break;
-
- case ME6000_AO_SYNC_HOLD: //0x00000001: Synchronous software
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
- if ((sync_mask &
- ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
- instance->ao_idx)) !=
- (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG)) {
- //Now we can set correct mode
- sync_mask |=
- ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx;
- sync_mask |= ME6000_AO_SYNC_HOLD << instance->ao_idx;
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- //Set triggering flag
- *instance->triggering_flags |= 0x1 << instance->ao_idx;
- break;
-
- case (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG): //0x00010001: Synchronous hardware
- PDEBUG("DIGITAL TRIGGER\n");
- ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
- if ((sync_mask &
- ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
- instance->ao_idx)) !=
- (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG)) {
- //Now we can set correct mode
- sync_mask |=
- (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
- instance->ao_idx;
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
- }
- //Set triggering flag
- *instance->triggering_flags |= 0x1 << instance->ao_idx;
- break;
- }
-// spin_unlock(instance->preload_reg_lock); // Moved down.
-
- if (instance->fifo) { //Activate ISM (remove 'stop' bits)
- ctrl &=
- ~(ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
- ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
- ctrl |= instance->ctrl_trg;
- ctrl &=
- ~(ME6000_AO_CTRL_BIT_STOP |
- ME6000_AO_CTRL_BIT_IMMEDIATE_STOP);
-
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- }
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-/// @note When flag 'ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS' is set than output is triggered. ALWAYS!
-
- PINFO("<%s> start mode= 0x%08x %s\n", __func__, mode,
- (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) ? "SYNCHRONOUS" :
- "");
- if (instance->fifo & ME6000_AO_HAS_FIFO) { // FIFO - Continous mode
- if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs
- //Add channel to start list
- outl(sync_mask |
- (ME6000_AO_SYNC_HOLD << instance->ao_idx),
- instance->preload_reg);
- 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));
-
- //Fire
- PINFO
- ("Fired all software synchronous outputs by software trigger.\n");
- outl(0x8000, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base,
- 0x8000);
-
- //Restore save settings
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
-
- } else if (!mode) { //Trigger outputs
-/* //Remove channel from start list
- outl(sync_mask & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
- 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));
-*/
- //Fire
- PINFO("Software trigger.\n");
- outl(0x8000, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base,
- 0x8000);
-
-/* //Restore save settings
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask);
-*/
- }
-/// @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.
-/// @note Because triggering is not working it can not be add to synchronous list. First 4 channels don't need this information, anyway.
- *instance->triggering_flags &= 0xFFFFFFF0;
- } else { // No FIFO - Single mode
- if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Fired all software synchronous outputs.
- tmp = ~(*instance->preload_flags | 0xFFFF0000);
- PINFO
- ("Fired all software synchronous outputs. mask:0x%08x\n",
- tmp);
- tmp |= sync_mask & 0xFFFF0000;
- // Add this channel to list
- tmp &= ~(ME6000_AO_SYNC_HOLD << instance->ao_idx);
-
- //Fire
- PINFO("Software trigger.\n");
- outl(tmp, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- tmp);
-
- //Restore save settings
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
-
- //Set all as triggered.
- *instance->triggering_flags = 0x0;
- } else if (!mode) { // Add this channel to list
- outl(sync_mask &
- ~(ME6000_AO_SYNC_HOLD << instance->ao_idx),
- instance->preload_reg);
- 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));
-
- //Fire
- PINFO("Software trigger.\n");
-
- //Restore save settings
- outl(sync_mask, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- sync_mask);
-
- //Set all as triggered.
- *instance->triggering_flags = 0x0;
- }
-
- }
- spin_unlock(instance->preload_reg_lock);
-
- instance->status = ao_status_single_run_wait;
-
- instance->timeout.delay = delay;
- instance->timeout.start_time = jiffies;
- instance->ao_control_task_flag = 1;
- queue_delayed_work(instance->me6000_workqueue,
- &instance->ao_control_task, 1);
-
- if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
- j = jiffies;
-
- //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
- wait_event_interruptible_timeout(instance->wait_queue,
- (instance->status !=
- ao_status_single_run_wait),
- (delay) ? delay +
- 1 : LONG_MAX);
-
- if (instance->status != ao_status_single_end) {
- PDEBUG("Single canceled.\n");
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on start of state machine interrupted.\n");
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
- ao_stop_immediately(instance);
- instance->status = ao_status_none;
- err = ME_ERRNO_SIGNAL;
- }
-
- if ((delay) && ((jiffies - j) >= delay)) {
- if (instance->status == ao_status_single_end) {
- PDEBUG("Timeout reached.\n");
- } else if ((jiffies - j) > delay) {
- PERROR
- ("Timeout reached. Not handled by control task!\n");
- ao_stop_immediately(instance);
- } else {
- PERROR
- ("Timeout reached. Signal come but status is strange: %d\n",
- instance->status);
- ao_stop_immediately(instance);
- }
-
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
- instance->status = ao_status_single_end;
- err = ME_ERRNO_TIMEOUT;
- }
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_ao_io_stream_config(me_subdevice_t *subdevice,
- struct file *filep,
- meIOStreamConfig_t *config_list,
- int count,
- meIOStreamTrigger_t *trigger,
- int fifo_irq_threshold, int flags)
-{
- me6000_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t ctrl;
- unsigned long cpu_flags;
- uint64_t conv_ticks;
- unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
- unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- conv_ticks =
- (uint64_t) conv_start_ticks_low +
- ((uint64_t) conv_start_ticks_high << 32);
-
- if (flags &
- ~(ME_IO_STREAM_CONFIG_HARDWARE_ONLY |
- ME_IO_STREAM_CONFIG_WRAPAROUND)) {
- PERROR("Invalid flags.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
- if (!(flags & ME_IO_STREAM_CONFIG_WRAPAROUND)) {
- PERROR
- ("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((trigger->iAcqStopTrigType != ME_TRIG_TYPE_NONE)
- || (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE)) {
- PERROR
- ("Hardware wraparound mode must be in infinite mode.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
- }
-
- if (count != 1) {
- PERROR("Only 1 entry in config list acceptable.\n");
- return ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
- }
-
- if (config_list[0].iChannel != 0) {
- PERROR("Invalid channel number specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (config_list[0].iStreamConfig != 0) {
- PERROR("Only one range available.\n");
- return ME_ERRNO_INVALID_STREAM_CONFIG;
- }
-
- if (config_list[0].iRef != ME_REF_AO_GROUND) {
- PERROR("Output is referenced to ground.\n");
- return ME_ERRNO_INVALID_REF;
- }
-
- if ((trigger->iAcqStartTicksLow != 0)
- || (trigger->iAcqStartTicksHigh != 0)) {
- PERROR
- ("Invalid acquisition start trigger argument specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_ARG;
- }
-
- if (config_list[0].iFlags) {
- PERROR("Invalid config list flag.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((trigger->iAcqStartTrigType != ME_TRIG_TYPE_SW)
- && (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_DIGITAL)) {
- PERROR("Invalid acquisition start trigger type specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
- }
-
- if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) {
- switch (trigger->iAcqStartTrigEdge) {
- case ME_TRIG_EDGE_RISING:
- case ME_TRIG_EDGE_FALLING:
- case ME_TRIG_EDGE_ANY:
- break;
-
- default:
- PERROR
- ("Invalid acquisition start trigger edge specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
- }
- }
-
- if ((trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW)
- && (trigger->iAcqStartTrigEdge != ME_TRIG_TYPE_NONE)) {
- PERROR("Invalid acquisition start trigger edge specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
- }
-
- if (trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW) {
- PERROR("Invalid scan start trigger type specified.\n");
- return ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
- }
-
- if (trigger->iConvStartTrigType != ME_TRIG_TYPE_TIMER) {
- PERROR("Invalid conv start trigger type specified.\n");
- return ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
- }
-
- if ((conv_ticks < ME6000_AO_MIN_CHAN_TICKS)
- || (conv_ticks > ME6000_AO_MAX_CHAN_TICKS)) {
- PERROR("Invalid conv start trigger argument specified.\n");
- return ME_ERRNO_INVALID_CONV_START_ARG;
- }
-
- if (trigger->iAcqStartTicksLow || trigger->iAcqStartTicksHigh) {
- PERROR("Invalid acq start trigger argument specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_ARG;
- }
-
- if (trigger->iScanStartTicksLow || trigger->iScanStartTicksHigh) {
- PERROR("Invalid scan start trigger argument specified.\n");
- return ME_ERRNO_INVALID_SCAN_START_ARG;
- }
-
- switch (trigger->iScanStopTrigType) {
- case ME_TRIG_TYPE_NONE:
- if (trigger->iScanStopCount != 0) {
- PERROR("Invalid scan stop count specified.\n");
- return ME_ERRNO_INVALID_SCAN_STOP_ARG;
- }
- break;
-
- case ME_TRIG_TYPE_COUNT:
- if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
- if (trigger->iScanStopCount <= 0) {
- PERROR("Invalid scan stop count specified.\n");
- return ME_ERRNO_INVALID_SCAN_STOP_ARG;
- }
- } else {
- PERROR("The continous mode has not 'scan' contects.\n");
- return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- }
- break;
-
- default:
- PERROR("Invalid scan stop trigger type specified.\n");
- return ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
- }
-
- switch (trigger->iAcqStopTrigType) {
- case ME_TRIG_TYPE_NONE:
- if (trigger->iAcqStopCount != 0) {
- PERROR("Invalid acq stop count specified.\n");
- return ME_ERRNO_INVALID_ACQ_STOP_ARG;
- }
- break;
-
- case ME_TRIG_TYPE_COUNT:
- if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
- PERROR("Invalid acq stop trigger type specified.\n");
- return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- }
-
- if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
- if (trigger->iAcqStopCount <= 0) {
- PERROR
- ("The continous mode has not 'scan' contects.\n");
- return ME_ERRNO_INVALID_ACQ_STOP_ARG;
- }
- }
-// else
-// {
-// PERROR("Invalid acq stop trigger type specified.\n");
-// return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-// }
-
- break;
-
- default:
- PERROR("Invalid acq stop trigger type specified.\n");
- return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
- }
-
- switch (trigger->iAcqStartTrigChan) {
- case ME_TRIG_CHAN_DEFAULT:
- case ME_TRIG_CHAN_SYNCHRONOUS:
- break;
-
- default:
- PERROR("Invalid acq start trigger channel specified.\n");
- return ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
- }
-
- ME_SUBDEVICE_ENTER;
-
- //Stop device
-
- //Cancel control task
- PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
-
- //Check if state machine is stopped.
- err = ao_stop_immediately(instance);
- if (err) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- //Reset control register. Block all actions. Disable IRQ. Disable FIFO.
- ctrl = ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
-
- //This is paranoic, but to be sure.
- instance->preloaded_count = 0;
- instance->data_count = 0;
- instance->circ_buf.head = 0;
- instance->circ_buf.tail = 0;
-
- /* Set mode. */
- if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { //Wraparound
- if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) { //Hardware wraparound
- PINFO("Hardware wraparound.\n");
- ctrl |= ME6000_AO_MODE_WRAPAROUND;
- instance->mode = ME6000_AO_HW_WRAP_MODE;
- } else { //Software wraparound
- PINFO("Software wraparound.\n");
- ctrl |= ME6000_AO_MODE_CONTINUOUS;
- instance->mode = ME6000_AO_SW_WRAP_MODE;
- }
- } else { //Continous
- PINFO("Continous.\n");
- ctrl |= ME6000_AO_MODE_CONTINUOUS;
- instance->mode = ME6000_AO_CONTINOUS;
- }
-
- //Set the trigger edge.
- if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Set the trigger type and edge for external trigger.
- PINFO("External digital trigger.\n");
- instance->start_mode = ME6000_AO_EXT_TRIG;
-
- switch (trigger->iAcqStartTrigEdge) {
- case ME_TRIG_EDGE_RISING:
- PINFO("Set the trigger edge: rising.\n");
- instance->ctrl_trg = 0x0;
- break;
-
- case ME_TRIG_EDGE_FALLING:
- PINFO("Set the trigger edge: falling.\n");
-// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
- instance->ctrl_trg = ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
- break;
-
- case ME_TRIG_EDGE_ANY:
- PINFO("Set the trigger edge: both edges.\n");
-// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
- instance->ctrl_trg =
- ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
- ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
- break;
- }
- } else {
- PINFO("Internal software trigger.\n");
- instance->start_mode = 0;
- }
-
- //Set the stop mode and value.
- if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of data
- instance->stop_mode = ME6000_AO_ACQ_STOP_MODE;
- instance->stop_count = trigger->iAcqStopCount;
- } else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of 'scans'
- instance->stop_mode = ME6000_AO_SCAN_STOP_MODE;
- instance->stop_count = trigger->iScanStopCount;
- } else { //Infinite
- instance->stop_mode = ME6000_AO_INF_STOP_MODE;
- instance->stop_count = 0;
- }
-
- PINFO("Stop count: %d.\n", instance->stop_count);
-
- if (trigger->iAcqStartTrigChan == ME_TRIG_CHAN_SYNCHRONOUS) { //Synchronous start
- instance->start_mode |= ME6000_AO_SYNC_HOLD;
- if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Externaly triggered
- PINFO("Synchronous start. Externaly trigger active.\n");
- instance->start_mode |= ME6000_AO_SYNC_EXT_TRIG;
- }
-#ifdef MEDEBUG_INFO
- else {
- PINFO
- ("Synchronous start. Externaly trigger dissabled.\n");
- }
-#endif
-
- }
- //Set speed
- outl(conv_ticks - 2, instance->timer_reg);
- PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%llx\n", instance->reg_base,
- instance->timer_reg - instance->reg_base, conv_ticks - 2);
- instance->hardware_stop_delay = (int)(conv_ticks * HZ) / ME6000_AO_BASE_FREQUENCY; //<== MUST be with cast!
-
- // Write the control word
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- //Set status.
- instance->status = ao_status_stream_configured;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice,
- struct file *filep,
- int time_out, int *count, int flags)
-{
- me6000_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- long t = 0;
- long j;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (!instance->circ_buf.buf) {
- PERROR("Circular buffer not exists.\n");
- return ME_ERRNO_INTERNAL;
- }
-
- if (time_out < 0) {
- PERROR("Invalid time_out specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (me_circ_buf_space(&instance->circ_buf)) { //The buffer is NOT full.
- *count = me_circ_buf_space(&instance->circ_buf);
- } else { //The buffer is full.
- if (time_out) {
- t = (time_out * HZ) / 1000;
-
- if (t == 0)
- t = 1;
- } else { //Max time.
- t = LONG_MAX;
- }
-
- *count = 0;
-
- j = jiffies;
-
- //Only runing process will interrupt this call. Interrupts are when FIFO HF is signaled.
- wait_event_interruptible_timeout(instance->wait_queue,
- ((me_circ_buf_space
- (&instance->circ_buf))
- || !(inl(instance->status_reg)
- &
- ME6000_AO_STATUS_BIT_FSM)),
- t);
-
- if (!(inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM)) {
- PERROR("AO subdevice is not running.\n");
- err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
- } else if (signal_pending(current)) {
- PERROR("Wait on values interrupted from signal.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- } else if ((jiffies - j) >= t) {
- PERROR("Wait on values timed out.\n");
- err = ME_ERRNO_TIMEOUT;
- } else { //Uff... all is good. Inform user about empty space.
- *count = me_circ_buf_space(&instance->circ_buf);
- }
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_ao_io_stream_start(me_subdevice_t *subdevice,
- struct file *filep,
- int start_mode, int time_out, int flags)
-{
- me6000_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long cpu_flags = 0;
- uint32_t status;
- uint32_t ctrl;
- uint32_t synch;
- int count = 0;
- int circ_buffer_count;
-
- unsigned long ref;
- unsigned long delay = 0;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (flags & ~ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
- PERROR("Invalid flags.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (time_out < 0) {
- PERROR("Invalid timeout specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if ((start_mode != ME_START_MODE_BLOCKING)
- && (start_mode != ME_START_MODE_NONBLOCKING)) {
- PERROR("Invalid start mode specified.\n");
- return ME_ERRNO_INVALID_START_MODE;
- }
-
- if (time_out) {
- delay = (time_out * HZ) / 1000;
- if (delay == 0)
- delay = 1;
- }
-
- switch (instance->status) { //Checking actual mode.
- case ao_status_stream_configured:
- case ao_status_stream_end:
- //Correct modes!
- break;
-
- //The device is in wrong mode.
- case ao_status_none:
- case ao_status_single_configured:
- case ao_status_single_run_wait:
- case ao_status_single_run:
- case ao_status_single_end_wait:
- PERROR
- ("Subdevice must be preinitialize correctly for streaming.\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
-
- case ao_status_stream_fifo_error:
- case ao_status_stream_buffer_error:
- case ao_status_stream_error:
- PDEBUG("Before restart broke stream 'STOP' must be caled.\n");
- return ME_STATUS_ERROR;
-
- case ao_status_stream_run_wait:
- case ao_status_stream_run:
- case ao_status_stream_end_wait:
- PDEBUG("Stream is already working.\n");
- return ME_ERRNO_SUBDEVICE_BUSY;
-
- default:
- instance->status = ao_status_stream_error;
- PERROR_CRITICAL("Status is in wrong state!\n");
- return ME_ERRNO_INTERNAL;
-
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (instance->mode == ME6000_AO_CONTINOUS) { //Continous
- instance->circ_buf.tail += instance->preloaded_count;
- instance->circ_buf.tail &= instance->circ_buf.mask;
- }
- circ_buffer_count = me_circ_buf_values(&instance->circ_buf);
-
- if (!circ_buffer_count && !instance->preloaded_count) { //No values in buffer
- ME_SUBDEVICE_EXIT;
- PERROR("No values in buffer!\n");
- return ME_ERRNO_LACK_OF_RESOURCES;
- }
-
- //Cancel control task
- PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
-
- //Stop device
- err = ao_stop_immediately(instance);
- if (err) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUBDEVICE_BUSY;
- }
- //Set values for single_read()
- instance->single_value = ME6000_AO_MAX_DATA + 1;
- instance->single_value_in_fifo = ME6000_AO_MAX_DATA + 1;
-
- //Setting stop points
- if (instance->stop_mode == ME6000_AO_SCAN_STOP_MODE) {
- instance->stop_data_count =
- instance->stop_count * circ_buffer_count;
- } else {
- instance->stop_data_count = instance->stop_count;
- }
-
- if ((instance->stop_data_count != 0)
- && (instance->stop_data_count < circ_buffer_count)) {
- PERROR("More data in buffer than previously set limit!\n");
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- //Check FIFO
- 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
- PINFO("Enableing FIFO.\n");
- ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-
- instance->preloaded_count = 0;
- instance->data_count = 0;
- } else { //Block IRQ
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- }
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
-
- //Fill FIFO <= Generaly this should be done by user pre-load call but this is second place to do it.
- status = inl(instance->status_reg);
- if (!(status & ME6000_AO_STATUS_BIT_EF)) { //FIFO empty
- if (instance->stop_data_count != 0) {
- count = ME6000_AO_FIFO_COUNT;
- } else {
- count =
- (ME6000_AO_FIFO_COUNT <
- instance->
- stop_data_count) ? ME6000_AO_FIFO_COUNT :
- instance->stop_data_count;
- }
-
- //Copy data
- count =
- ao_write_data(instance, count, instance->preloaded_count);
-
- if (count < 0) { //This should never happend!
- PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
- }
- //Set pre-load features.
- spin_lock(instance->preload_reg_lock);
- synch = inl(instance->preload_reg);
- synch &=
- ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->
- ao_idx);
- synch |=
- (instance->start_mode & ~ME6000_AO_EXT_TRIG) << instance->ao_idx;
- outl(synch, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->preload_reg - instance->reg_base, synch);
- spin_unlock(instance->preload_reg_lock);
-
- //Default count is '0'
- if (instance->mode == ME6000_AO_CONTINOUS) { //Continous
- instance->preloaded_count = 0;
- instance->circ_buf.tail += count;
- instance->circ_buf.tail &= instance->circ_buf.mask;
- } else { //Wraparound
- instance->preloaded_count += count;
- instance->data_count += count;
-
- //Special case: Infinite wraparound with less than FIFO datas always should runs in hardware mode.
- if ((instance->stop_mode == ME6000_AO_INF_STOP_MODE)
- && (circ_buffer_count <= ME6000_AO_FIFO_COUNT)) { //Change to hardware wraparound
- PDEBUG
- ("Changeing mode from software wraparound to hardware wraparound.\n");
- //Copy all data
- count =
- ao_write_data(instance, circ_buffer_count,
- instance->preloaded_count);
- ctrl &= ~ME6000_AO_CTRL_MODE_MASK;
- ctrl |= ME6000_AO_MODE_WRAPAROUND;
- }
-
- if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator.
- instance->preloaded_count = 0;
- } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend!
- PERROR_CRITICAL
- ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
- }
-
- //Set status to 'wait for start'
- instance->status = ao_status_stream_run_wait;
-
- status = inl(instance->status_reg);
- //Start state machine and interrupts
- PINFO("<%s:%d> Start state machine.\n", __func__, __LINE__);
- ctrl &= ~(ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP);
- if (instance->start_mode == ME6000_AO_EXT_TRIG) {
- PDEBUG("DIGITAL TRIGGER\n");
- ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
- }
- if (!(status & ME6000_AO_STATUS_BIT_HF)) { //More than half!
- 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
- PINFO("<%s:%d> Start interrupts.\n", __func__,
- __LINE__);
- ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- }
- }
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- //Trigger output
- PINFO("<%s> start mode= 0x%x %s\n", __func__, instance->start_mode,
- (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) ? "SYNCHRONOUS" :
- "");
- if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs
- spin_lock(instance->preload_reg_lock);
- synch = inl(instance->preload_reg);
- //Add channel to start list
- outl(synch | (ME6000_AO_SYNC_HOLD << instance->ao_idx),
- instance->preload_reg);
- 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));
-
- //Fire
- PINFO
- ("Fired all software synchronous outputs by software trigger.\n");
- outl(0x8000, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base, 0x8000);
-
- //Restore save settings
- outl(synch, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base, synch);
- spin_unlock(instance->preload_reg_lock);
- } else if (!instance->start_mode) { //Trigger outputs
-/*
- spin_lock(instance->preload_reg_lock);
- synch = inl(instance->preload_reg);
- //Remove channel from start list
- outl(synch & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
- 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));
-*/
- //Fire
- PINFO("Software trigger.\n");
- outl(0x8000, instance->single_reg);
- PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base, 0x8000);
-
-/*
- //Restore save settings
- outl(synch, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch);
- spin_unlock(instance->preload_reg_lock);
-*/
- }
- // Set control task's timeout
- instance->timeout.delay = delay;
- instance->timeout.start_time = jiffies;
-
- if (status & ME6000_AO_STATUS_BIT_HF) { //Less than half but not empty!
- PINFO("Less than half.\n");
- if (instance->stop_data_count == 0) {
- count = ME6000_AO_FIFO_COUNT / 2;
- } else {
- count =
- ((ME6000_AO_FIFO_COUNT / 2) <
- instance->stop_data_count) ? ME6000_AO_FIFO_COUNT /
- 2 : instance->stop_data_count;
- }
-
- //Copy data
- count =
- ao_write_data(instance, count, instance->preloaded_count);
-
- if (count < 0) { //This should never happend!
- PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
-
- if (instance->mode == ME6000_AO_CONTINOUS) { //Continous
- instance->circ_buf.tail += count;
- instance->circ_buf.tail &= instance->circ_buf.mask;
- } else { //Wraparound
- instance->data_count += count;
- instance->preloaded_count += count;
-
- if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator.
- instance->preloaded_count = 0;
- } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend!
- PERROR_CRITICAL
- ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
- }
-
- status = inl(instance->status_reg);
- if (!(status & ME6000_AO_STATUS_BIT_HF)) { //More than half!
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- PINFO("<%s:%d> Start interrupts.\n", __func__,
- __LINE__);
- ctrl = inl(instance->ctrl_reg);
- ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
- }
- }
- //Special case: Limited wraparound with less than HALF FIFO datas need work around to generate first interrupt.
- if ((instance->stop_mode != ME6000_AO_INF_STOP_MODE)
- && (instance->mode == ME6000_AO_SW_WRAP_MODE)
- && (circ_buffer_count <= (ME6000_AO_FIFO_COUNT / 2))) { //Put more data to FIFO
- PINFO("Limited wraparound with less than HALF FIFO datas.\n");
- if (instance->preloaded_count) { //This should never happend!
- PERROR_CRITICAL
- ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
-
- while (instance->stop_data_count > instance->data_count) { //Maximum data not set jet.
- //Copy to buffer
- if (circ_buffer_count != ao_write_data(instance, circ_buffer_count, 0)) { //This should never happend!
- PERROR_CRITICAL
- ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
- ME_SUBDEVICE_EXIT;
- return ME_ERRNO_INTERNAL;
- }
- instance->data_count += circ_buffer_count;
-
- if (!((status = inl(instance->status_reg)) & ME6000_AO_STATUS_BIT_HF)) { //FIFO is more than half. Enable IRQ and end copy.
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
-
- spin_lock_irqsave(&instance->subdevice_lock,
- cpu_flags);
- PINFO("<%s:%d> Start interrupts.\n",
- __func__, __LINE__);
- ctrl = inl(instance->ctrl_reg);
- ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg -
- instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
- break;
- }
- }
- }
- // Schedule control task
- instance->ao_control_task_flag = 1;
- queue_delayed_work(instance->me6000_workqueue,
- &instance->ao_control_task, 1);
-
- if (start_mode == ME_START_MODE_BLOCKING) { //Wait for start.
- ref = jiffies;
- //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
- wait_event_interruptible_timeout(instance->wait_queue,
- (instance->status !=
- ao_status_stream_run_wait),
- (delay) ? delay +
- 1 : LONG_MAX);
-
- if ((instance->status != ao_status_stream_run)
- && (instance->status != ao_status_stream_end)) {
- PDEBUG("Starting stream canceled. %d\n",
- instance->status);
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on start of state machine interrupted.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- }
-
- if ((delay) && ((jiffies - ref) >= delay)) {
- if (instance->status != ao_status_stream_run) {
- if (instance->status == ao_status_stream_end) {
- PDEBUG("Timeout reached.\n");
- } else if ((jiffies - ref) > delay) {
- PERROR
- ("Timeout reached. Not handled by control task!\n");
- ao_stop_immediately(instance);
- } else {
- PERROR
- ("Timeout reached. Signal come but status is strange: %d\n",
- instance->status);
- ao_stop_immediately(instance);
- }
-
- instance->ao_control_task_flag = 0;
- cancel_delayed_work(&instance->ao_control_task);
- instance->status = ao_status_stream_end;
- err = ME_ERRNO_TIMEOUT;
- }
- }
- }
-
- ME_SUBDEVICE_EXIT;
- return err;
-}
-
-static int me6000_ao_io_stream_status(me_subdevice_t *subdevice,
- struct file *filep,
- int wait,
- int *status, int *values, int flags)
-{
- me6000_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((wait != ME_WAIT_NONE) && (wait != ME_WAIT_IDLE)) {
- PERROR("Invalid wait argument specified.\n");
- *status = ME_STATUS_INVALID;
- return ME_ERRNO_INVALID_WAIT;
- }
-
- ME_SUBDEVICE_ENTER;
-
- switch (instance->status) {
- case ao_status_single_configured:
- case ao_status_single_end:
- case ao_status_stream_configured:
- case ao_status_stream_end:
- case ao_status_stream_fifo_error:
- case ao_status_stream_buffer_error:
- case ao_status_stream_error:
- *status = ME_STATUS_IDLE;
- break;
-
- case ao_status_single_run_wait:
- case ao_status_single_run:
- case ao_status_single_end_wait:
- case ao_status_stream_run_wait:
- case ao_status_stream_run:
- case ao_status_stream_end_wait:
- *status = ME_STATUS_BUSY;
- break;
-
- case ao_status_none:
- default:
- *status =
- (inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM) ?
- ME_STATUS_BUSY : ME_STATUS_IDLE;
- break;
- }
-
- if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) {
- //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
- wait_event_interruptible_timeout(instance->wait_queue,
- ((instance->status !=
- ao_status_single_run_wait)
- && (instance->status !=
- ao_status_single_run)
- && (instance->status !=
- ao_status_single_end_wait)
- && (instance->status !=
- ao_status_stream_run_wait)
- && (instance->status !=
- ao_status_stream_run)
- && (instance->status !=
- ao_status_stream_end_wait)),
- LONG_MAX);
-
- if (instance->status != ao_status_stream_end) {
- PDEBUG("Wait for IDLE canceled. %d\n",
- instance->status);
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Wait for IDLE interrupted.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- }
-
- *status = ME_STATUS_IDLE;
- }
-
- *values = me_circ_buf_space(&instance->circ_buf);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_ao_io_stream_stop(me_subdevice_t *subdevice,
- struct file *filep,
- int stop_mode, int flags)
-{ /// @note Stop work and empty buffer and FIFO
- int err = ME_ERRNO_SUCCESS;
- me6000_ao_subdevice_t *instance;
- unsigned long cpu_flags;
- volatile uint32_t ctrl;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (flags & ~ME_IO_STREAM_STOP_PRESERVE_BUFFERS) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((stop_mode != ME_STOP_MODE_IMMEDIATE)
- && (stop_mode != ME_STOP_MODE_LAST_VALUE)) {
- PERROR("Invalid stop mode specified.\n");
- return ME_ERRNO_INVALID_STOP_MODE;
- }
-
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (instance->status < ao_status_stream_configured) {
- //There is nothing to stop!
- PERROR("Subdevice not in streaming mode. %d\n",
- instance->status);
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-
- ME_SUBDEVICE_ENTER;
-
- //Mark as stopping. => Software stop.
- instance->status = ao_status_stream_end_wait;
-
- if (stop_mode == ME_STOP_MODE_IMMEDIATE) { //Stopped now!
- err = ao_stop_immediately(instance);
- } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
- ctrl = inl(instance->ctrl_reg) & ME6000_AO_CTRL_MODE_MASK;
- if (ctrl == ME6000_AO_MODE_WRAPAROUND) { //Hardware wraparound => Hardware stop.
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl |= ME6000_AO_CTRL_BIT_STOP;
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
- }
- //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
- wait_event_interruptible_timeout(instance->wait_queue,
- (instance->status !=
- ao_status_stream_end_wait),
- LONG_MAX);
-
- if (instance->status != ao_status_stream_end) {
- PDEBUG("Stopping stream canceled.\n");
- err = ME_ERRNO_CANCELLED;
- }
-
- if (signal_pending(current)) {
- PERROR("Stopping stream interrupted.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- }
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl |= ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- if (!flags) { //Reset FIFO
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_FIFO;
- }
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
-
- if (!flags) { //Reset software buffer
- instance->circ_buf.head = 0;
- instance->circ_buf.tail = 0;
- instance->preloaded_count = 0;
- instance->data_count = 0;
- }
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_ao_io_stream_write(me_subdevice_t *subdevice,
- struct file *filep,
- int write_mode,
- int *values, int *count, int flags)
-{
- int err = ME_ERRNO_SUCCESS;
- me6000_ao_subdevice_t *instance;
- unsigned long cpu_flags = 0;
- uint32_t reg_copy;
-
- int copied_from_user = 0;
- int left_to_copy_from_user = *count;
-
- int copied_values;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- //Checking arguments
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
- PERROR("Not a streaming ao.\n");
- return ME_ERRNO_NOT_SUPPORTED;
- }
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (*count <= 0) {
- PERROR("Invalid count of values specified.\n");
- return ME_ERRNO_INVALID_VALUE_COUNT;
- }
-
- if (values == NULL) {
- PERROR("Invalid address of values specified.\n");
- return ME_ERRNO_INVALID_POINTER;
- }
-
- if ((instance->status == ao_status_none) || (instance->status == ao_status_single_configured)) { //The device is in single mode.
- PERROR
- ("Subdevice must be preinitialize correctly for streaming.\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
-
- switch (write_mode) {
- case ME_WRITE_MODE_PRELOAD:
-
- //Device must be stopped.
- if ((instance->status != ao_status_stream_configured)
- && (instance->status != ao_status_stream_end)) {
- PERROR
- ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
- }
- break;
- case ME_WRITE_MODE_NONBLOCKING:
- case ME_WRITE_MODE_BLOCKING:
- /// @note In blocking mode: When device is not runing and there is not enought space call will blocked up!
- /// @note Some other thread must empty buffer by strating engine.
- break;
-
- default:
- PERROR("Invalid write mode specified.\n");
- return ME_ERRNO_INVALID_WRITE_MODE;
- }
-
- if (instance->mode & ME6000_AO_WRAP_MODE) { //Wraparound mode. Device must be stopped.
- if ((instance->status != ao_status_stream_configured)
- && (instance->status != ao_status_stream_end)) {
- PERROR
- ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
- return ME_ERRNO_INVALID_WRITE_MODE;
- }
- }
-
- if ((instance->mode == ME6000_AO_HW_WRAP_MODE)
- && (write_mode != ME_WRITE_MODE_PRELOAD)) {
-/*
- PERROR("Only 'pre-load' write is acceptable in hardware wraparound mode.\n");
- return ME_ERRNO_PREVIOUS_CONFIG;
-*/
- //This is transparent for user.
- PDEBUG("Changing write_mode to ME_WRITE_MODE_PRELOAD.\n");
- write_mode = ME_WRITE_MODE_PRELOAD;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (write_mode == ME_WRITE_MODE_PRELOAD) { //Init enviroment - preload
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- reg_copy = inl(instance->ctrl_reg);
- //Check FIFO
- if (!(reg_copy & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO not active. Enable it.
- reg_copy |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
- outl(reg_copy, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- reg_copy);
- instance->preloaded_count = 0;
- }
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- }
-
- while (1) {
- //Copy to buffer. This step is common for all modes.
- copied_from_user =
- ao_get_data_from_user(instance, left_to_copy_from_user,
- values + (*count -
- left_to_copy_from_user));
- left_to_copy_from_user -= copied_from_user;
-
- reg_copy = inl(instance->status_reg);
- 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.
- PERROR("Broken pipe in write.\n");
- err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
- break;
- }
-
- 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!
-
- // Block interrupts.
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- reg_copy = inl(instance->ctrl_reg);
- reg_copy &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- outl(reg_copy, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- reg_copy);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- //Fast copy
- copied_values =
- ao_write_data(instance, ME6000_AO_FIFO_COUNT / 2,
- 0);
- if (copied_values > 0) {
- instance->circ_buf.tail += copied_values;
- instance->circ_buf.tail &=
- instance->circ_buf.mask;
- continue;
- }
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
-
- // Activate interrupts.
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- reg_copy = inl(instance->ctrl_reg);
- reg_copy |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- outl(reg_copy, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- reg_copy);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- if (copied_values == 0) { //This was checked and never should happend!
- PERROR_CRITICAL("COPY FINISH WITH 0!\n");
- }
-
- if (copied_values < 0) { //This was checked and never should happend!
- PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
- instance->status = ao_status_stream_fifo_error;
- err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
- break;
- }
- }
-
- if (!left_to_copy_from_user) { //All datas were copied.
- break;
- } else { //Not all datas were copied.
- if (instance->mode & ME6000_AO_WRAP_MODE) { //Error too much datas! Wraparound is limited in size!
- PERROR
- ("Too much data for wraparound mode! Exceeded size of %ld.\n",
- ME6000_AO_CIRC_BUF_COUNT - 1);
- err = ME_ERRNO_RING_BUFFER_OVERFLOW;
- break;
- }
-
- if (write_mode != ME_WRITE_MODE_BLOCKING) { //Non blocking calls
- break;
- }
-
- wait_event_interruptible(instance->wait_queue,
- me_circ_buf_space(&instance->
- circ_buf));
-
- if (signal_pending(current)) {
- PERROR("Writing interrupted by signal.\n");
- instance->status = ao_status_none;
- ao_stop_immediately(instance);
- err = ME_ERRNO_SIGNAL;
- break;
- }
-
- if (instance->status == ao_status_none) { //Reset
- PERROR("Writing interrupted by reset.\n");
- err = ME_ERRNO_CANCELLED;
- break;
- }
- }
- }
-
- if (write_mode == ME_WRITE_MODE_PRELOAD) { //Copy data to FIFO - preload
- copied_values =
- ao_write_data_pooling(instance, ME6000_AO_FIFO_COUNT,
- instance->preloaded_count);
- instance->preloaded_count += copied_values;
- instance->data_count += copied_values;
-
- if ((instance->mode == ME6000_AO_HW_WRAP_MODE)
- && (me_circ_buf_values(&instance->circ_buf) >
- ME6000_AO_FIFO_COUNT)) {
- PERROR
- ("Too much data for hardware wraparound mode! Exceeded size of %d.\n",
- ME6000_AO_FIFO_COUNT);
- err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
- }
- }
-
- *count = *count - left_to_copy_from_user;
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static irqreturn_t me6000_ao_isr(int irq, void *dev_id)
-{
- me6000_ao_subdevice_t *instance = dev_id;
- uint32_t irq_status;
- uint32_t ctrl;
- uint32_t status;
- int count = 0;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (irq != instance->irq) {
- PERROR("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- irq_status = inl(instance->irq_status_reg);
- if (!(irq_status & (ME6000_IRQ_STATUS_BIT_AO_HF << instance->ao_idx))) {
- PINFO("%ld Shared interrupt. %s(): ID=%d: status_reg=0x%04X\n",
- jiffies, __func__, instance->ao_idx, irq_status);
- return IRQ_NONE;
- }
-
- if (!instance->circ_buf.buf) {
- instance->status = ao_status_stream_error;
- PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n");
- //Block interrupts. Stop machine.
- ctrl = inl(instance->ctrl_reg);
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- ctrl |=
- ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- //Inform user
- wake_up_interruptible_all(&instance->wait_queue);
- return IRQ_HANDLED;
- }
-
- status = inl(instance->status_reg);
- if (!(status & ME6000_AO_STATUS_BIT_FSM)) { //Too late. Not working! END? BROKEN PIPE?
- /// @note Error checking was moved to separate task.
- PDEBUG("Interrupt come but ISM is not working!\n");
- //Block interrupts. Stop machine.
- ctrl = inl(instance->ctrl_reg);
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- ctrl |=
- ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
-
- /// @note User notification was also moved to separate task.
- return IRQ_HANDLED;
- }
- //General procedure. Process more datas.
-
-#ifdef MEDEBUG_DEBUG
- if (!me_circ_buf_values(&instance->circ_buf)) { //Buffer is empty!
- PDEBUG("Circular buffer empty!\n");
- }
-#endif
-
- //Check FIFO
- if (status & ME6000_AO_STATUS_BIT_HF) { //OK less than half
-
- //Block interrupts
- ctrl = inl(instance->ctrl_reg);
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
-
- do {
- //Calculate how many should be copied.
- count =
- (instance->stop_data_count) ? instance->
- stop_data_count -
- instance->data_count : ME6000_AO_FIFO_COUNT / 2;
- if (ME6000_AO_FIFO_COUNT / 2 < count) {
- count = ME6000_AO_FIFO_COUNT / 2;
- }
- //Copy data
- if (instance->mode == ME6000_AO_CONTINOUS) { //Continous
- count = ao_write_data(instance, count, 0);
- if (count > 0) {
- instance->circ_buf.tail += count;
- instance->circ_buf.tail &=
- instance->circ_buf.mask;
- instance->data_count += count;
-
- if ((instance->status == ao_status_stream_end_wait) && !me_circ_buf_values(&instance->circ_buf)) { //Stoping. Whole buffer was copied.
- break;
- }
- }
- } else if ((instance->mode == ME6000_AO_SW_WRAP_MODE) && ((ctrl & ME6000_AO_CTRL_MODE_MASK) == ME6000_AO_MODE_CONTINUOUS)) { //Wraparound (software)
- if (instance->status == ao_status_stream_end_wait) { //We stoping => Copy to the end of the buffer.
- count =
- ao_write_data(instance, count, 0);
- } else { //Copy in wraparound mode.
- count =
- ao_write_data_wraparound(instance,
- count,
- instance->
- preloaded_count);
- }
-
- if (count > 0) {
- instance->data_count += count;
- instance->preloaded_count += count;
- instance->preloaded_count %=
- me_circ_buf_values(&instance->
- circ_buf);
-
- if ((instance->status == ao_status_stream_end_wait) && !instance->preloaded_count) { //Stoping. Whole buffer was copied.
- break;
- }
- }
- }
-
- if ((count <= 0) || (instance->stop_data_count && (instance->stop_data_count <= instance->data_count))) { //End of work.
- break;
- }
- } //Repeat if still is under half fifo
- while ((status =
- inl(instance->status_reg)) & ME6000_AO_STATUS_BIT_HF);
-
- //Unblock interrupts
- ctrl = inl(instance->ctrl_reg);
- if (count >= 0) { //Copy was successful.
- if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. No more interrupts.
- PDEBUG("Finishing work. Interrupt disabled.\n");
- instance->status = ao_status_stream_end_wait;
- } else if (count > 0) { //Normal work. Enable interrupt.
- PDEBUG("Normal work. Enable interrupt.\n");
- ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
- } else { //Normal work but there are no more data in buffer. Interrupt blocked. stream_write() will unblock it.
- PDEBUG
- ("No data in software buffer. Interrupt blocked.\n");
- }
- } else { //Error during copy.
- instance->status = ao_status_stream_fifo_error;
- }
-
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- } else { //?? more than half
- PDEBUG
- ("Interrupt come but FIFO more than half full! Reset interrupt.\n");
- }
-
- PINFO("ISR: Buffer count: %d.(T:%d H:%d)\n",
- me_circ_buf_values(&instance->circ_buf), instance->circ_buf.tail,
- instance->circ_buf.head);
- PINFO("ISR: Stop count: %d.\n", instance->stop_count);
- PINFO("ISR: Stop data count: %d.\n", instance->stop_data_count);
- PINFO("ISR: Data count: %d.\n", instance->data_count);
-
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
-
- //Inform user
- wake_up_interruptible_all(&instance->wait_queue);
-
- return IRQ_HANDLED;
-}
-
-static void me6000_ao_destructor(struct me_subdevice *subdevice)
-{
- me6000_ao_subdevice_t *instance;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- instance->ao_control_task_flag = 0;
-
- // Reset subdevice to asure clean exit.
- me6000_ao_io_reset_subdevice(subdevice, NULL,
- ME_IO_RESET_SUBDEVICE_NO_FLAGS);
-
- // Remove any tasks from work queue. This is paranoic because it was done allready in reset().
- if (!cancel_delayed_work(&instance->ao_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue.
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(2);
- }
-
- if (instance->fifo & ME6000_AO_HAS_FIFO) {
- if (instance->irq) {
- free_irq(instance->irq, instance);
- instance->irq = 0;
- }
-
- if (instance->circ_buf.buf) {
- PDEBUG("free circ_buf = %p size=%d",
- instance->circ_buf.buf,
- PAGE_SHIFT << ME6000_AO_CIRC_BUF_SIZE_ORDER);
- free_pages((unsigned long)instance->circ_buf.buf,
- ME6000_AO_CIRC_BUF_SIZE_ORDER);
- }
- instance->circ_buf.buf = NULL;
- }
-
- me_subdevice_deinit(&instance->base);
- kfree(instance);
-}
-
-me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
- spinlock_t *preload_reg_lock,
- uint32_t *preload_flags,
- uint32_t *triggering_flags,
- int ao_idx,
- int fifo,
- int irq,
- int high_range,
- struct workqueue_struct *me6000_wq)
-{
- me6000_ao_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed ID=%d.\n", ao_idx);
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me6000_ao_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me6000_ao_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->preload_reg_lock = preload_reg_lock;
- subdevice->preload_flags = preload_flags;
- subdevice->triggering_flags = triggering_flags;
-
- /* Store analog output index */
- subdevice->ao_idx = ao_idx;
-
- /* Store if analog output has fifo */
- subdevice->fifo = fifo;
-
- if (subdevice->fifo & ME6000_AO_HAS_FIFO) {
- /* Allocate and initialize circular buffer */
- subdevice->circ_buf.mask = ME6000_AO_CIRC_BUF_COUNT - 1;
- subdevice->circ_buf.buf =
- (void *)__get_free_pages(GFP_KERNEL,
- ME6000_AO_CIRC_BUF_SIZE_ORDER);
- PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf,
- ME6000_AO_CIRC_BUF_SIZE);
-
- if (!subdevice->circ_buf.buf) {
- PERROR
- ("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
-
- memset(subdevice->circ_buf.buf, 0, ME6000_AO_CIRC_BUF_SIZE);
- } else {
- subdevice->circ_buf.mask = 0;
- subdevice->circ_buf.buf = NULL;
- }
- subdevice->circ_buf.head = 0;
- subdevice->circ_buf.tail = 0;
-
- subdevice->status = ao_status_none;
- subdevice->ao_control_task_flag = 0;
- subdevice->timeout.delay = 0;
- subdevice->timeout.start_time = jiffies;
-
- /* Initialize wait queue */
- init_waitqueue_head(&subdevice->wait_queue);
-
- /* Initialize single value to 0V */
- subdevice->single_value = 0x8000;
- subdevice->single_value_in_fifo = 0x8000;
-
- /* Initialize range boarders */
- if (high_range) {
- subdevice->min = ME6000_AO_MIN_RANGE_HIGH;
- subdevice->max = ME6000_AO_MAX_RANGE_HIGH;
- } else {
- subdevice->min = ME6000_AO_MIN_RANGE;
- subdevice->max = ME6000_AO_MAX_RANGE;
- }
-
- /* Register interrupt service routine */
-
- if (subdevice->fifo & ME6000_AO_HAS_FIFO) {
- subdevice->irq = irq;
- if (request_irq(subdevice->irq, me6000_ao_isr,
- IRQF_DISABLED | IRQF_SHARED,
- ME6000_NAME, subdevice)) {
- PERROR("Cannot get interrupt line.\n");
- PDEBUG("free circ_buf = %p size=%d",
- subdevice->circ_buf.buf,
- PAGE_SHIFT << ME6000_AO_CIRC_BUF_SIZE_ORDER);
- free_pages((unsigned long)subdevice->circ_buf.buf,
- ME6000_AO_CIRC_BUF_SIZE_ORDER);
- subdevice->circ_buf.buf = NULL;
- kfree(subdevice);
- return NULL;
- }
- PINFO("Registered irq=%d.\n", subdevice->irq);
- } else {
- subdevice->irq = 0;
- }
-
- /* Initialize registers */
- // Only streamed subdevices support interrupts. For the rest this register has no meaning.
- subdevice->irq_status_reg = reg_base + ME6000_AO_IRQ_STATUS_REG;
- subdevice->preload_reg = reg_base + ME6000_AO_PRELOAD_REG;
-
- if (ao_idx == 0) {
- subdevice->ctrl_reg = reg_base + ME6000_AO_00_CTRL_REG;
- subdevice->status_reg = reg_base + ME6000_AO_00_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME6000_AO_00_FIFO_REG;
- subdevice->timer_reg = reg_base + ME6000_AO_00_TIMER_REG;
- subdevice->irq_reset_reg =
- reg_base + ME6000_AO_00_IRQ_RESET_REG;
- subdevice->single_reg = reg_base + ME6000_AO_00_SINGLE_REG;
- } else if (ao_idx == 1) {
- subdevice->ctrl_reg = reg_base + ME6000_AO_01_CTRL_REG;
- subdevice->status_reg = reg_base + ME6000_AO_01_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME6000_AO_01_FIFO_REG;
- subdevice->timer_reg = reg_base + ME6000_AO_01_TIMER_REG;
- subdevice->irq_reset_reg =
- reg_base + ME6000_AO_01_IRQ_RESET_REG;
- subdevice->single_reg = reg_base + ME6000_AO_01_SINGLE_REG;
- } else if (ao_idx == 2) {
- subdevice->ctrl_reg = reg_base + ME6000_AO_02_CTRL_REG;
- subdevice->status_reg = reg_base + ME6000_AO_02_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME6000_AO_02_FIFO_REG;
- subdevice->timer_reg = reg_base + ME6000_AO_02_TIMER_REG;
- subdevice->irq_reset_reg =
- reg_base + ME6000_AO_02_IRQ_RESET_REG;
- subdevice->single_reg = reg_base + ME6000_AO_02_SINGLE_REG;
- } else if (ao_idx == 3) {
- subdevice->ctrl_reg = reg_base + ME6000_AO_03_CTRL_REG;
- subdevice->status_reg = reg_base + ME6000_AO_03_STATUS_REG;
- subdevice->fifo_reg = reg_base + ME6000_AO_03_FIFO_REG;
- subdevice->timer_reg = reg_base + ME6000_AO_03_TIMER_REG;
- subdevice->irq_reset_reg =
- reg_base + ME6000_AO_03_IRQ_RESET_REG;
- subdevice->single_reg = reg_base + ME6000_AO_03_SINGLE_REG;
- } else {
- subdevice->ctrl_reg = reg_base + ME6000_AO_DUMY;
- subdevice->fifo_reg = reg_base + ME6000_AO_DUMY;
- subdevice->timer_reg = reg_base + ME6000_AO_DUMY;
- subdevice->irq_reset_reg = reg_base + ME6000_AO_DUMY;
- subdevice->single_reg = reg_base + ME6000_AO_DUMY;
-
- subdevice->status_reg = reg_base + ME6000_AO_SINGLE_STATUS_REG;
- if (ao_idx == 4) {
- subdevice->single_reg =
- reg_base + ME6000_AO_04_SINGLE_REG;
- } else if (ao_idx == 5) {
- subdevice->single_reg =
- reg_base + ME6000_AO_05_SINGLE_REG;
- } else if (ao_idx == 6) {
- subdevice->single_reg =
- reg_base + ME6000_AO_06_SINGLE_REG;
- } else if (ao_idx == 7) {
- subdevice->single_reg =
- reg_base + ME6000_AO_07_SINGLE_REG;
- } else if (ao_idx == 8) {
- subdevice->single_reg =
- reg_base + ME6000_AO_08_SINGLE_REG;
- } else if (ao_idx == 9) {
- subdevice->single_reg =
- reg_base + ME6000_AO_09_SINGLE_REG;
- } else if (ao_idx == 10) {
- subdevice->single_reg =
- reg_base + ME6000_AO_10_SINGLE_REG;
- } else if (ao_idx == 11) {
- subdevice->single_reg =
- reg_base + ME6000_AO_11_SINGLE_REG;
- } else if (ao_idx == 12) {
- subdevice->single_reg =
- reg_base + ME6000_AO_12_SINGLE_REG;
- } else if (ao_idx == 13) {
- subdevice->single_reg =
- reg_base + ME6000_AO_13_SINGLE_REG;
- } else if (ao_idx == 14) {
- subdevice->single_reg =
- reg_base + ME6000_AO_14_SINGLE_REG;
- } else if (ao_idx == 15) {
- subdevice->single_reg =
- reg_base + ME6000_AO_15_SINGLE_REG;
- } else {
- PERROR_CRITICAL("WRONG SUBDEVICE ID=%d!", ao_idx);
- me_subdevice_deinit((me_subdevice_t *) subdevice);
- if (subdevice->fifo) {
- free_pages((unsigned long)subdevice->circ_buf.
- buf, ME6000_AO_CIRC_BUF_SIZE_ORDER);
- }
- subdevice->circ_buf.buf = NULL;
- kfree(subdevice);
- return NULL;
- }
- }
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Override base class methods. */
- subdevice->base.me_subdevice_destructor = me6000_ao_destructor;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me6000_ao_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me6000_ao_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me6000_ao_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me6000_ao_io_single_write;
- subdevice->base.me_subdevice_io_stream_config =
- me6000_ao_io_stream_config;
- subdevice->base.me_subdevice_io_stream_new_values =
- me6000_ao_io_stream_new_values;
- subdevice->base.me_subdevice_io_stream_write =
- me6000_ao_io_stream_write;
- subdevice->base.me_subdevice_io_stream_start =
- me6000_ao_io_stream_start;
- subdevice->base.me_subdevice_io_stream_status =
- me6000_ao_io_stream_status;
- subdevice->base.me_subdevice_io_stream_stop = me6000_ao_io_stream_stop;
- subdevice->base.me_subdevice_query_number_channels =
- me6000_ao_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me6000_ao_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me6000_ao_query_subdevice_caps;
- subdevice->base.me_subdevice_query_subdevice_caps_args =
- me6000_ao_query_subdevice_caps_args;
- subdevice->base.me_subdevice_query_range_by_min_max =
- me6000_ao_query_range_by_min_max;
- subdevice->base.me_subdevice_query_number_ranges =
- me6000_ao_query_number_ranges;
- subdevice->base.me_subdevice_query_range_info =
- me6000_ao_query_range_info;
- subdevice->base.me_subdevice_query_timer = me6000_ao_query_timer;
-
- //prepare work queue and work function
- subdevice->me6000_workqueue = me6000_wq;
-
-/* workqueue API changed in kernel 2.6.20 */
- INIT_DELAYED_WORK(&subdevice->ao_control_task,
- me6000_ao_work_control_task);
-
- if (subdevice->fifo) { //Set speed
- outl(ME6000_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
- subdevice->hardware_stop_delay = HZ / 10; //100ms
- }
-
- return subdevice;
-}
-
-/** @brief Stop presentation. Preserve FIFOs.
-*
-* @param instance The subdevice instance (pointer).
-*/
-inline int ao_stop_immediately(me6000_ao_subdevice_t *instance)
-{
- unsigned long cpu_flags;
- uint32_t ctrl;
- int timeout;
- int i;
- uint32_t single_mask;
-
- if (instance->ao_idx < ME6000_AO_SINGLE_STATUS_OFFSET)
- single_mask = 0x0000;
- else
- single_mask = 0x0001 << (instance->ao_idx -
- ME6000_AO_SINGLE_STATUS_OFFSET);
-
- timeout =
- (instance->hardware_stop_delay >
- (HZ / 10)) ? instance->hardware_stop_delay : HZ / 10;
- for (i = 0; i <= timeout; i++) {
- if (instance->fifo) {
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- ME6000_AO_CTRL_BIT_STOP |
- ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
- ctrl &=
- ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
- ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- if (!(inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM)) { // Exit.
- break;
- }
- } else {
- if (!(inl(instance->status_reg) & single_mask)) { // Exit.
- break;
- }
- }
-
- PINFO("<%s> Wait for stop: %d\n", __func__, i);
-
- //Still working!
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
-
- if (i > timeout) {
- PERROR_CRITICAL("FSM IS BUSY!\n");
- return ME_ERRNO_INTERNAL;
- }
- return ME_ERRNO_SUCCESS;
-}
-
-/** @brief Copy data from circular buffer to fifo (fast) in wraparound.
-* @note This is time critical function. Checking is done at begining and end only.
-* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied data.
-* @return On error/success: 0. No datas were copied => no data in buffer.
-* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
-*/
-inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count,
- int start_pos)
-{ /// @note This is time critical function!
- uint32_t status;
- uint32_t value;
- int pos =
- (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
- int local_count = count;
- int i = 1;
-
- if (count <= 0) { //Wrong count!
- return 0;
- }
-
- while (i < local_count) {
- //Get value from buffer
- value = *(instance->circ_buf.buf + pos);
- //Prepare it
- if (instance->ao_idx & 0x1) {
- value <<= 16;
- }
- //Put value to FIFO
- outl(value, instance->fifo_reg);
- //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);
-
- pos++;
- pos &= instance->circ_buf.mask;
- if (pos == instance->circ_buf.head) {
- pos = instance->circ_buf.tail;
- }
- i++;
- }
-
- status = inl(instance->status_reg);
- if (!(status & ME6000_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied!
- PERROR("idx=%d FIFO is full before all datas were copied!\n",
- instance->ao_idx);
- return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
- } else { //Add last value
- value = *(instance->circ_buf.buf + pos);
- if (instance->ao_idx & 0x1) {
- value <<= 16;
- }
- //Put value to FIFO
- outl(value, instance->fifo_reg);
- //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);
- }
-
- PINFO("idx=%d WRAPAROUND LOADED %d values\n", instance->ao_idx,
- local_count);
- return local_count;
-}
-
-/** @brief Copy data from software buffer to fifo (fast).
-* @note This is time critical function. Checking is done at begining and end only.
-* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied data.
-* @return On error/success: 0. No datas were copied => no data in buffer.
-* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
-*/
-inline int ao_write_data(me6000_ao_subdevice_t *instance, int count,
- int start_pos)
-{ /// @note This is time critical function!
- uint32_t status;
- uint32_t value;
- int pos =
- (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
- int local_count = count;
- int max_count;
- int i = 1;
-
- if (count <= 0) { //Wrong count!
- return 0;
- }
-
- max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
- if (max_count <= 0) { //No data to copy!
- return 0;
- }
-
- if (max_count < count) {
- local_count = max_count;
- }
-
- while (i < local_count) {
- //Get value from buffer
- value = *(instance->circ_buf.buf + pos);
- //Prepare it
- if (instance->ao_idx & 0x1) {
- value <<= 16;
- }
- //Put value to FIFO
- outl(value, instance->fifo_reg);
- //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);
-
- pos++;
- pos &= instance->circ_buf.mask;
- i++;
- }
-
- status = inl(instance->status_reg);
- if (!(status & ME6000_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied!
- PERROR("idx=%d FIFO is full before all datas were copied!\n",
- instance->ao_idx);
- return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
- } else { //Add last value
- value = *(instance->circ_buf.buf + pos);
- if (instance->ao_idx & 0x1) {
- value <<= 16;
- }
- //Put value to FIFO
- outl(value, instance->fifo_reg);
- //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);
- }
-
- PINFO("idx=%d FAST LOADED %d values\n", instance->ao_idx, local_count);
- return local_count;
-}
-
-/** @brief Copy data from software buffer to fifo (slow).
-* @note This is slow function that copy all data from buffer to FIFO with full control.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied values.
-* @return On error/success: 0. FIFO was full at begining.
-* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
-*/
-inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count,
- int start_pos)
-{ /// @note This is slow function!
- uint32_t status;
- uint32_t value;
- int pos =
- (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
- int local_count = count;
- int i;
- int max_count;
-
- if (count <= 0) { //Wrong count!
- PERROR("idx=%d SLOW LOADED: Wrong count!\n", instance->ao_idx);
- return 0;
- }
-
- max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
- if (max_count <= 0) { //No data to copy!
- PERROR("idx=%d SLOW LOADED: No data to copy!\n",
- instance->ao_idx);
- return 0;
- }
-
- if (max_count < count) {
- local_count = max_count;
- }
-
- for (i = 0; i < local_count; i++) {
- status = inl(instance->status_reg);
- if (!(status & ME6000_AO_STATUS_BIT_FF)) { //FIFO is full!
- return i;
- }
- //Get value from buffer
- value = *(instance->circ_buf.buf + pos);
- //Prepare it
- if (instance->ao_idx & 0x1) {
- value <<= 16;
- }
- //Put value to FIFO
- outl(value, instance->fifo_reg);
- //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);
-
- pos++;
- pos &= instance->circ_buf.mask;
- }
-
- PINFO("idx=%d SLOW LOADED %d values\n", instance->ao_idx, local_count);
- return local_count;
-}
-
-/** @brief Copy data from user space to circular buffer.
-* @param instance The subdevice instance (pointer).
-* @param count Number of datas in user space.
-* @param user_values Buffer's pointer.
-*
-* @return On success: Number of copied values.
-* @return On error: -ME_ERRNO_INTERNAL.
-*/
-inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count,
- int *user_values)
-{
- int i, err;
- int empty_space;
- int copied;
- int value;
-
- empty_space = me_circ_buf_space(&instance->circ_buf);
- //We have only this space free.
- copied = (count < empty_space) ? count : empty_space;
- for (i = 0; i < copied; i++) { //Copy from user to buffer
- if ((err = get_user(value, (int *)(user_values + i)))) {
- PERROR
- ("idx=%d BUFFER LOADED: get_user(0x%p) return an error: %d\n",
- instance->ao_idx, user_values + i, err);
- return -ME_ERRNO_INTERNAL;
- }
- /// @note The analog output in me6000 series has size of 16 bits.
- *(instance->circ_buf.buf + instance->circ_buf.head) =
- (uint16_t) value;
- instance->circ_buf.head++;
- instance->circ_buf.head &= instance->circ_buf.mask;
- }
-
- PINFO("idx=%d BUFFER LOADED %d values\n", instance->ao_idx, copied);
- return copied;
-}
-
-static void me6000_ao_work_control_task(struct work_struct *work)
-{
- me6000_ao_subdevice_t *instance;
- unsigned long cpu_flags = 0;
- uint32_t status;
- uint32_t ctrl;
- uint32_t synch;
- int reschedule = 0;
- int signaling = 0;
- uint32_t single_mask;
-
- instance =
- container_of((void *)work, me6000_ao_subdevice_t, ao_control_task);
- PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
- instance->ao_idx);
-
- status = inl(instance->status_reg);
- PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->status_reg - instance->reg_base, status);
-
-/// @note AO_STATUS_BIT_FSM doesn't work as should be for pure single channels (idx>=4)
-// single_mask = (instance->ao_idx-ME6000_AO_SINGLE_STATUS_OFFSET < 0) ? 0x0000 : (0x0001 << (instance->ao_idx-ME6000_AO_SINGLE_STATUS_OFFSET));
- single_mask = *instance->triggering_flags & (0x1 << instance->ao_idx);
-
- switch (instance->status) { // Checking actual mode.
-
- // Not configured for work.
- case ao_status_none:
- break;
-
- //This are stable modes. No need to do anything. (?)
- case ao_status_single_configured:
- case ao_status_stream_configured:
- case ao_status_stream_fifo_error:
- case ao_status_stream_buffer_error:
- case ao_status_stream_error:
- PERROR("Shouldn't be running!.\n");
- break;
-
- // Single modes
- case ao_status_single_run_wait:
- case ao_status_single_run:
- case ao_status_single_end_wait:
- if (instance->fifo) { // Extra registers.
- if (!(status & ME6000_AO_STATUS_BIT_FSM)) { // State machine is not working.
- if (((instance->fifo & ME6000_AO_HAS_FIFO)
- && (!(status & ME6000_AO_STATUS_BIT_EF)))
- || (!(instance->fifo & ME6000_AO_HAS_FIFO))) { // Single is in end state.
- PDEBUG
- ("Single call has been complited.\n");
-
- // Set correct value for single_read();
- instance->single_value =
- instance->single_value_in_fifo;
-
- // Set status as 'ao_status_single_end'
- instance->status = ao_status_single_end;
-
- spin_lock(instance->preload_reg_lock);
- if ((single_mask) && (*instance->preload_flags & (ME6000_AO_SYNC_HOLD << instance->ao_idx))) { // This is one of synchronous start channels. Set all as triggered.
- *instance->triggering_flags =
- 0x00000000;
- } else {
- //Set this channel as triggered (none active).
- *instance->triggering_flags &=
- ~(0x1 << instance->ao_idx);
- }
- spin_unlock(instance->preload_reg_lock);
-
- // Signal the end.
- signaling = 1;
- // Wait for stop ISM.
- reschedule = 1;
-
- break;
- }
- }
- // Check timeout.
- if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
- PDEBUG("Timeout reached.\n");
- // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
- spin_lock_irqsave(&instance->subdevice_lock,
- cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- ME6000_AO_CTRL_BIT_STOP |
- ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
- ctrl &=
- ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
- ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
- ctrl &=
- ~(ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
- ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
- //Disabling FIFO
- ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_FIFO;
-
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg -
- instance->reg_base, ctrl);
- spin_unlock_irqrestore(&instance->
- subdevice_lock,
- cpu_flags);
-
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
-
- spin_lock(instance->preload_reg_lock);
- //Remove from synchronous start. Block triggering from this output.
- synch = inl(instance->preload_reg);
- synch &=
- ~((ME6000_AO_SYNC_HOLD |
- ME6000_AO_SYNC_EXT_TRIG) << instance->
- ao_idx);
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO - set to single safe mode
- synch |=
- ME6000_AO_SYNC_HOLD << instance->
- ao_idx;
- }
- outl(synch, instance->preload_reg);
- PDEBUG_REG
- ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- synch);
- //Set this channel as triggered (none active).
- *instance->triggering_flags &=
- ~(0x1 << instance->ao_idx);
- spin_unlock(instance->preload_reg_lock);
-
- // Set correct value for single_read();
- instance->single_value_in_fifo =
- instance->single_value;
-
- instance->status = ao_status_single_end;
-
- // Signal the end.
- signaling = 1;
- }
- } else { // No extra registers.
-/*
- if (!(status & single_mask))
- {// State machine is not working.
- PDEBUG("Single call has been complited.\n");
-
- // Set correct value for single_read();
- instance->single_value = instance->single_value_in_fifo;
-
- // Set status as 'ao_status_single_end'
- instance->status = ao_status_single_end;
-
- // Signal the end.
- signaling = 1;
- // Wait for stop ISM.
- reschedule = 1;
-
- break;
- }
-*/
- if (!single_mask) { // Was triggered.
- PDEBUG("Single call has been complited.\n");
-
- // Set correct value for single_read();
- instance->single_value =
- instance->single_value_in_fifo;
-
- // Set status as 'ao_status_single_end'
- instance->status = ao_status_single_end;
-
- // Signal the end.
- signaling = 1;
-
- break;
- }
- // Check timeout.
- if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
- PDEBUG("Timeout reached.\n");
-
- spin_lock(instance->preload_reg_lock);
- //Remove from synchronous start. Block triggering from this output.
- synch = inl(instance->preload_reg);
- synch &=
- ~(ME6000_AO_SYNC_EXT_TRIG << instance->
- ao_idx);
- synch |=
- ME6000_AO_SYNC_HOLD << instance->ao_idx;
-
- outl(synch, instance->preload_reg);
- PDEBUG_REG
- ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- synch);
- //Set this channel as triggered (none active).
- *instance->triggering_flags &=
- ~(0x1 << instance->ao_idx);
- spin_unlock(instance->preload_reg_lock);
-
- // Restore old settings.
- PDEBUG("Write old value back to register.\n");
- outl(instance->single_value,
- instance->single_reg);
- PDEBUG_REG
- ("single_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->single_reg - instance->reg_base,
- instance->single_value);
-
- // Set correct value for single_read();
- instance->single_value_in_fifo =
- instance->single_value;
-
- instance->status = ao_status_single_end;
-
- // Signal the end.
- signaling = 1;
- }
- }
-
- // Wait for stop.
- reschedule = 1;
- break;
-
- case ao_status_stream_end:
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO
- PERROR_CRITICAL
- ("Streaming on single device! This feature is not implemented in this version!\n");
- instance->status = ao_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
- }
- case ao_status_single_end:
- if (instance->fifo) { // Extra registers.
- if (status & ME6000_AO_STATUS_BIT_FSM) { // State machine is working but the status is set to end. Force stop.
-
- // Wait for stop.
- reschedule = 1;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- ME6000_AO_CTRL_BIT_IMMEDIATE_STOP |
- ME6000_AO_CTRL_BIT_STOP;
- ctrl &=
- ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
- ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
- } else { // No extra registers.
-/*
- if (status & single_mask)
- {// State machine is working but the status is set to end. Force stop.
-
- // Wait for stop.
- reschedule = 1;
- }
-*/
- }
- break;
-
- // Stream modes
- case ao_status_stream_run_wait:
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO
- PERROR_CRITICAL
- ("Streaming on single device! This feature is not implemented in this version!\n");
- instance->status = ao_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
- }
-
- if (status & ME6000_AO_STATUS_BIT_FSM) { // State machine is working. Waiting for start finish.
- instance->status = ao_status_stream_run;
-
- // Signal end of this step
- signaling = 1;
- } else { // State machine is not working.
- if (!(status & ME6000_AO_STATUS_BIT_EF)) { // FIFO is empty. Procedure has started and finish already!
- instance->status = ao_status_stream_end;
-
- // Signal the end.
- signaling = 1;
- // Wait for stop.
- reschedule = 1;
- break;
- }
- }
-
- // Check timeout.
- if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout
- PDEBUG("Timeout reached.\n");
- // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- ctrl = inl(instance->ctrl_reg);
- ctrl |=
- ME6000_AO_CTRL_BIT_STOP |
- ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
- ctrl &=
- ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
- ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
- outl(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base,
- ctrl);
- spin_unlock_irqrestore(&instance->subdevice_lock,
- cpu_flags);
-
- //Reset interrupt latch
- inl(instance->irq_reset_reg);
-
- spin_lock(instance->preload_reg_lock);
- //Remove from synchronous start. Block triggering from this output.
- synch = inl(instance->preload_reg);
- synch &=
- ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
- instance->ao_idx);
- outl(synch, instance->preload_reg);
- PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->preload_reg - instance->reg_base,
- synch);
- spin_unlock(instance->preload_reg_lock);
-
- instance->status = ao_status_stream_end;
-
- // Signal the end.
- signaling = 1;
- }
- // Wait for stop.
- reschedule = 1;
- break;
-
- case ao_status_stream_run:
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO
- PERROR_CRITICAL
- ("Streaming on single device! This feature is not implemented in this version!\n");
- instance->status = ao_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
- }
-
- if (!(status & ME6000_AO_STATUS_BIT_FSM)) { // State machine is not working. This is an error.
- // BROKEN PIPE!
- if (!(status & ME6000_AO_STATUS_BIT_EF)) { // FIFO is empty.
- if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty.
- if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. Requed data shown.
- PDEBUG
- ("ISM stoped. No data in FIFO. Buffer is not empty.\n");
- instance->status =
- ao_status_stream_end;
- } else {
- PERROR
- ("Output stream has been broken. ISM stoped. No data in FIFO. Buffer is not empty.\n");
- instance->status =
- ao_status_stream_buffer_error;
- }
- } else { // Software buffer is empty.
- PDEBUG
- ("ISM stoped. No data in FIFO. Buffer is empty.\n");
- instance->status = ao_status_stream_end;
- }
- } else { // There are still datas in FIFO.
- if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty.
- PERROR
- ("Output stream has been broken. ISM stoped but some data in FIFO and buffer.\n");
- } else { // Software buffer is empty.
- PERROR
- ("Output stream has been broken. ISM stoped but some data in FIFO. Buffer is empty.\n");
- }
- instance->status = ao_status_stream_fifo_error;
-
- }
-
- // Signal the failure.
- signaling = 1;
- break;
- }
- // Wait for stop.
- reschedule = 1;
- break;
-
- case ao_status_stream_end_wait:
- if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO
- PERROR_CRITICAL
- ("Streaming on single device! This feature is not implemented in this version!\n");
- instance->status = ao_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
- }
-
- if (!(status & ME6000_AO_STATUS_BIT_FSM)) { // State machine is not working. Waiting for stop finish.
- instance->status = ao_status_stream_end;
- signaling = 1;
- }
- // State machine is working.
- reschedule = 1;
- break;
-
- default:
- PERROR_CRITICAL("Status is in wrong state (%d)!\n",
- instance->status);
- instance->status = ao_status_stream_error;
- // Signal the end.
- signaling = 1;
- break;
-
- }
-
- if (signaling) { //Signal it.
- wake_up_interruptible_all(&instance->wait_queue);
- }
-
- if (instance->ao_control_task_flag && reschedule) { // Reschedule task
- queue_delayed_work(instance->me6000_workqueue,
- &instance->ao_control_task, 1);
- } else {
- PINFO("<%s> Ending control task.\n", __func__);
- }
-
-}
-
-static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice,
- int unit,
- int *min,
- int *max, int *maxdata, int *range)
-{
- me6000_ao_subdevice_t *instance;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if ((*max - *min) < 0) {
- PERROR("Invalid minimum and maximum values specified.\n");
- return ME_ERRNO_INVALID_MIN_MAX;
- }
-
- if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
- if ((*max <= (instance->max + 1000)) && (*min >= instance->min)) {
- *min = instance->min;
- *max = instance->max;
- *maxdata = ME6000_AO_MAX_DATA;
- *range = 0;
- } else {
- PERROR("No matching range available.\n");
- return ME_ERRNO_NO_RANGE;
- }
- } else {
- PERROR("Invalid physical unit specified.\n");
- return ME_ERRNO_INVALID_UNIT;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice,
- int unit, int *count)
-{
- me6000_ao_subdevice_t *instance;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
- *count = 1;
- } else {
- *count = 0;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_range_info(me_subdevice_t *subdevice,
- int range,
- int *unit,
- int *min, int *max, int *maxdata)
-{
- me6000_ao_subdevice_t *instance;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (range == 0) {
- *unit = ME_UNIT_VOLT;
- *min = instance->min;
- *max = instance->max;
- *maxdata = ME6000_AO_MAX_DATA;
- } else {
- PERROR("Invalid range number specified.\n");
- return ME_ERRNO_INVALID_RANGE;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_timer(me_subdevice_t *subdevice,
- int timer,
- int *base_frequency,
- long long *min_ticks, long long *max_ticks)
-{
- me6000_ao_subdevice_t *instance;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (instance->fifo) { //Streaming device.
- *base_frequency = ME6000_AO_BASE_FREQUENCY;
- if (timer == ME_TIMER_ACQ_START) {
- *min_ticks = ME6000_AO_MIN_ACQ_TICKS;
- *max_ticks = ME6000_AO_MAX_ACQ_TICKS;
- } else if (timer == ME_TIMER_CONV_START) {
- *min_ticks = ME6000_AO_MIN_CHAN_TICKS;
- *max_ticks = ME6000_AO_MAX_CHAN_TICKS;
- }
- } else { //Not streaming device!
- *base_frequency = 0;
- *min_ticks = 0;
- *max_ticks = 0;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- me6000_ao_subdevice_t *instance;
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- *number = 1;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- me6000_ao_subdevice_t *instance;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- *type = ME_TYPE_AO;
- *subtype =
- (instance->
- fifo & ME6000_AO_HAS_FIFO) ? ME_SUBTYPE_STREAMING :
- ME_SUBTYPE_SINGLE;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- me6000_ao_subdevice_t *instance;
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- *caps =
- ME_CAPS_AO_TRIG_SYNCHRONOUS | ((instance->fifo) ? ME_CAPS_AO_FIFO :
- ME_CAPS_NONE);
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
- int cap, int *args, int count)
-{
- me6000_ao_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- instance = (me6000_ao_subdevice_t *) subdevice;
-
- PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
- if (count != 1) {
- PERROR("Invalid capability argument count.\n");
- return ME_ERRNO_INVALID_CAP_ARG_COUNT;
- }
-
- switch (cap) {
- case ME_CAP_AI_FIFO_SIZE:
- args[0] = (instance->fifo) ? ME6000_AO_FIFO_COUNT : 0;
- break;
-
- case ME_CAP_AI_BUFFER_SIZE:
- args[0] =
- (instance->circ_buf.buf) ? ME6000_AO_CIRC_BUF_COUNT : 0;
- break;
-
- default:
- PERROR("Invalid capability.\n");
- err = ME_ERRNO_INVALID_CAP;
- args[0] = 0;
- }
-
- return err;
-}
diff --git a/drivers/staging/meilhaus/me6000_ao.h b/drivers/staging/meilhaus/me6000_ao.h
deleted file mode 100644
index d86fb29..0000000
--- a/drivers/staging/meilhaus/me6000_ao.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * @file me6000_ao.h
- *
- * @brief Meilhaus ME-6000 analog output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME6000_AO_H_
-#define _ME6000_AO_H_
-
-#include "mesubdevice.h"
-#include "mecirc_buf.h"
-#include "meioctl.h"
-
-#ifdef __KERNEL__
-
-#define ME6000_AO_MAX_SUBDEVICES 16
-#define ME6000_AO_FIFO_COUNT 8192
-
-#define ME6000_AO_BASE_FREQUENCY 33000000L
-
-#define ME6000_AO_MIN_ACQ_TICKS 0LL
-#define ME6000_AO_MAX_ACQ_TICKS 0LL
-
-#define ME6000_AO_MIN_CHAN_TICKS 66LL
-#define ME6000_AO_MAX_CHAN_TICKS 0xFFFFFFFFLL
-
-#define ME6000_AO_MIN_RANGE -10000000
-#define ME6000_AO_MAX_RANGE 9999694
-
-#define ME6000_AO_MIN_RANGE_HIGH 0
-#define ME6000_AO_MAX_RANGE_HIGH 49999237
-
-#define ME6000_AO_MAX_DATA 0xFFFF
-
-#ifdef ME_SYNAPSE
-# define ME6000_AO_CIRC_BUF_SIZE_ORDER 8 // 2^n PAGES =>> Maximum value of 1MB for Synapse
-#else
-# define ME6000_AO_CIRC_BUF_SIZE_ORDER 5 // 2^n PAGES =>> 128KB
-#endif
-#define ME6000_AO_CIRC_BUF_SIZE PAGE_SIZE<<ME6000_AO_CIRC_BUF_SIZE_ORDER // Buffer size in bytes.
-
-# ifdef _CBUFF_32b_t
-# define ME6000_AO_CIRC_BUF_COUNT ((ME6000_AO_CIRC_BUF_SIZE) / sizeof(uint32_t)) // Size in values
-# else
-# define ME6000_AO_CIRC_BUF_COUNT ((ME6000_AO_CIRC_BUF_SIZE) / sizeof(uint16_t)) // Size in values
-# endif
-
-# define ME6000_AO_CONTINOUS 0x0
-# define ME6000_AO_WRAP_MODE 0x1
-# define ME6000_AO_HW_MODE 0x2
-
-# define ME6000_AO_HW_WRAP_MODE (ME6000_AO_WRAP_MODE | ME6000_AO_HW_MODE)
-# define ME6000_AO_SW_WRAP_MODE ME6000_AO_WRAP_MODE
-
-# define ME6000_AO_INF_STOP_MODE 0x0
-# define ME6000_AO_ACQ_STOP_MODE 0x1
-# define ME6000_AO_SCAN_STOP_MODE 0x2
-
-# define ME6000_AO_EXTRA_HARDWARE 0x1
-# define ME6000_AO_HAS_FIFO 0x2
-
-typedef enum ME6000_AO_STATUS {
- ao_status_none = 0,
- ao_status_single_configured,
- ao_status_single_run_wait,
- ao_status_single_run,
- ao_status_single_end_wait,
- ao_status_single_end,
- ao_status_stream_configured,
- ao_status_stream_run_wait,
- ao_status_stream_run,
- ao_status_stream_end_wait,
- ao_status_stream_end,
- ao_status_stream_fifo_error,
- ao_status_stream_buffer_error,
- ao_status_stream_error,
- ao_status_last
-} ME6000_AO_STATUS;
-
-typedef struct me6000_ao_timeout {
- unsigned long start_time;
- unsigned long delay;
-} me6000_ao_timeout_t;
-
-/**
- * @brief The ME-6000 analog output subdevice class.
- */
-typedef struct me6000_ao_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
- unsigned int ao_idx;
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *preload_reg_lock; /**< Spin lock to protect preload_reg from concurrent access. */
-
- uint32_t *preload_flags;
- uint32_t *triggering_flags;
-
- /* Hardware feautres */
- unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */
- int fifo; /**< If set this device has a FIFO. */
-
- //Range
- int min;
- int max;
-
- int single_value; /**< Mirror of the output value in single mode. */
- int single_value_in_fifo; /**< Mirror of the value written in single mode. */
- uint32_t ctrl_trg; /**< Mirror of the trigger settings. */
-
- volatile int mode; /**< Flags used for storing SW wraparound setup*/
- int stop_mode; /**< The user defined stop condition flag. */
- unsigned int start_mode;
- unsigned int stop_count; /**< The user defined dates presentation end count. */
- unsigned int stop_data_count; /**< The stop presentation count. */
- unsigned int data_count; /**< The real presentation count. */
- unsigned int preloaded_count; /**< The next data addres in buffer. <= for wraparound mode. */
- int hardware_stop_delay; /**< The time that stop can take. This is only to not show hardware bug to user. */
-
- volatile enum ME6000_AO_STATUS status; /**< The current stream status flag. */
- me6000_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
-
- /* Registers *//**< All registers are 32 bits long. */
- unsigned long ctrl_reg;
- unsigned long status_reg;
- unsigned long fifo_reg;
- unsigned long single_reg;
- unsigned long timer_reg;
- unsigned long irq_status_reg;
- unsigned long preload_reg;
- unsigned long irq_reset_reg;
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-
- /* Software buffer */
- me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. */
- wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
-
- struct workqueue_struct *me6000_workqueue;
- struct delayed_work ao_control_task;
-
- volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
-
-} me6000_ao_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-6000 analog output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
- * @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
- * @param ao_idx Subdevice number.
- * @param fifo Flag set if subdevice has hardware FIFO.
- * @param irq IRQ number.
- * @param high_range Flag set if subdevice has high curren output.
- * @param me6000_wq Queue for asynchronous task (1 queue for all subdevice on 1 board).
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
- spinlock_t * preload_reg_lock,
- uint32_t * preload_flags,
- uint32_t * triggering_flags,
- int ao_idx,
- int fifo,
- int irq,
- int high_range,
- struct workqueue_struct
- *me6000_wq);
-
-#endif //__KERNEL__
-#endif //_ME6000_AO_H_
diff --git a/drivers/staging/meilhaus/me6000_ao_reg.h b/drivers/staging/meilhaus/me6000_ao_reg.h
deleted file mode 100644
index eb8f46e..0000000
--- a/drivers/staging/meilhaus/me6000_ao_reg.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/**
- * @file me6000_ao_reg.h
- *
- * @brief ME-6000 analog output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME6000_AO_REG_H_
-#define _ME6000_AO_REG_H_
-
-#ifdef __KERNEL__
-
-// AO
-#define ME6000_AO_00_CTRL_REG 0x00 // R/W
-#define ME6000_AO_00_STATUS_REG 0x04 // R/_
-#define ME6000_AO_00_FIFO_REG 0x08 // _/W
-#define ME6000_AO_00_SINGLE_REG 0x0C // R/W
-#define ME6000_AO_00_TIMER_REG 0x10 // _/W
-
-#define ME6000_AO_01_CTRL_REG 0x18 // R/W
-#define ME6000_AO_01_STATUS_REG 0x1C // R/_
-#define ME6000_AO_01_FIFO_REG 0x20 // _/W
-#define ME6000_AO_01_SINGLE_REG 0x24 // R/W
-#define ME6000_AO_01_TIMER_REG 0x28 // _/W
-
-#define ME6000_AO_02_CTRL_REG 0x30 // R/W
-#define ME6000_AO_02_STATUS_REG 0x34 // R/_
-#define ME6000_AO_02_FIFO_REG 0x38 // _/W
-#define ME6000_AO_02_SINGLE_REG 0x3C // R/W
-#define ME6000_AO_02_TIMER_REG 0x40 // _/W
-
-#define ME6000_AO_03_CTRL_REG 0x48 // R/W
-#define ME6000_AO_03_STATUS_REG 0x4C // R/_
-#define ME6000_AO_03_FIFO_REG 0x50 // _/W
-#define ME6000_AO_03_SINGLE_REG 0x54 // R/W
-#define ME6000_AO_03_TIMER_REG 0x58 // _/W
-
-#define ME6000_AO_SINGLE_STATUS_REG 0xA4 // R/_
-#define ME6000_AO_SINGLE_STATUS_OFFSET 4 //The first single subdevice => bit 0 in ME6000_AO_SINGLE_STATUS_REG.
-
-#define ME6000_AO_04_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_04_SINGLE_REG 0x74 // _/W
-
-#define ME6000_AO_05_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_05_SINGLE_REG 0x78 // _/W
-
-#define ME6000_AO_06_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_06_SINGLE_REG 0x7C // _/W
-
-#define ME6000_AO_07_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_07_SINGLE_REG 0x80 // _/W
-
-#define ME6000_AO_08_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_08_SINGLE_REG 0x84 // _/W
-
-#define ME6000_AO_09_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_09_SINGLE_REG 0x88 // _/W
-
-#define ME6000_AO_10_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_10_SINGLE_REG 0x8C // _/W
-
-#define ME6000_AO_11_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_11_SINGLE_REG 0x90 // _/W
-
-#define ME6000_AO_12_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_12_SINGLE_REG 0x94 // _/W
-
-#define ME6000_AO_13_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_13_SINGLE_REG 0x98 // _/W
-
-#define ME6000_AO_14_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_14_SINGLE_REG 0x9C // _/W
-
-#define ME6000_AO_15_STATUS_REG ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_15_SINGLE_REG 0xA0 // _/W
-
-//ME6000_AO_CTRL_REG
-#define ME6000_AO_MODE_SINGLE 0x00
-#define ME6000_AO_MODE_WRAPAROUND 0x01
-#define ME6000_AO_MODE_CONTINUOUS 0x02
-#define ME6000_AO_CTRL_MODE_MASK (ME6000_AO_MODE_WRAPAROUND | ME6000_AO_MODE_CONTINUOUS)
-
-#define ME6000_AO_CTRL_BIT_MODE_WRAPAROUND 0x001
-#define ME6000_AO_CTRL_BIT_MODE_CONTINUOUS 0x002
-#define ME6000_AO_CTRL_BIT_STOP 0x004
-#define ME6000_AO_CTRL_BIT_ENABLE_FIFO 0x008
-#define ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG 0x010
-#define ME6000_AO_CTRL_BIT_EX_TRIG_EDGE 0x020
-#define ME6000_AO_CTRL_BIT_ENABLE_IRQ 0x040
-#define ME6000_AO_CTRL_BIT_IMMEDIATE_STOP 0x080
-#define ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH 0x800
-
-//ME6000_AO_STATUS_REG
-#define ME6000_AO_STATUS_BIT_FSM 0x01
-#define ME6000_AO_STATUS_BIT_FF 0x02
-#define ME6000_AO_STATUS_BIT_HF 0x04
-#define ME6000_AO_STATUS_BIT_EF 0x08
-
-#define ME6000_AO_PRELOAD_REG 0xA8 // R/W ///ME6000_AO_SYNC_REG <==> ME6000_AO_PRELOAD_REG
-/*
-#define ME6000_AO_SYNC_HOLD_0 0x00000001
-#define ME6000_AO_SYNC_HOLD_1 0x00000002
-#define ME6000_AO_SYNC_HOLD_2 0x00000004
-#define ME6000_AO_SYNC_HOLD_3 0x00000008
-#define ME6000_AO_SYNC_HOLD_4 0x00000010
-#define ME6000_AO_SYNC_HOLD_5 0x00000020
-#define ME6000_AO_SYNC_HOLD_6 0x00000040
-#define ME6000_AO_SYNC_HOLD_7 0x00000080
-#define ME6000_AO_SYNC_HOLD_8 0x00000100
-#define ME6000_AO_SYNC_HOLD_9 0x00000200
-#define ME6000_AO_SYNC_HOLD_10 0x00000400
-#define ME6000_AO_SYNC_HOLD_11 0x00000800
-#define ME6000_AO_SYNC_HOLD_12 0x00001000
-#define ME6000_AO_SYNC_HOLD_13 0x00002000
-#define ME6000_AO_SYNC_HOLD_14 0x00004000
-#define ME6000_AO_SYNC_HOLD_15 0x00008000
-*/
-#define ME6000_AO_SYNC_HOLD 0x00000001
-/*
-#define ME6000_AO_SYNC_EXT_TRIG_0 0x00010000
-#define ME6000_AO_SYNC_EXT_TRIG_1 0x00020000
-#define ME6000_AO_SYNC_EXT_TRIG_2 0x00040000
-#define ME6000_AO_SYNC_EXT_TRIG_3 0x00080000
-#define ME6000_AO_SYNC_EXT_TRIG_4 0x00100000
-#define ME6000_AO_SYNC_EXT_TRIG_5 0x00200000
-#define ME6000_AO_SYNC_EXT_TRIG_6 0x00400000
-#define ME6000_AO_SYNC_EXT_TRIG_7 0x00800000
-#define ME6000_AO_SYNC_EXT_TRIG_8 0x01000000
-#define ME6000_AO_SYNC_EXT_TRIG_9 0x02000000
-#define ME6000_AO_SYNC_EXT_TRIG_10 0x04000000
-#define ME6000_AO_SYNC_EXT_TRIG_11 0x08000000
-#define ME6000_AO_SYNC_EXT_TRIG_12 0x10000000
-#define ME6000_AO_SYNC_EXT_TRIG_13 0x20000000
-#define ME6000_AO_SYNC_EXT_TRIG_14 0x40000000
-#define ME6000_AO_SYNC_EXT_TRIG_15 0x80000000
-*/
-#define ME6000_AO_SYNC_EXT_TRIG 0x00010000
-
-#define ME6000_AO_EXT_TRIG 0x80000000
-
-// AO-IRQ
-#define ME6000_AO_IRQ_STATUS_REG 0x60 // R/_
-#define ME6000_AO_00_IRQ_RESET_REG 0x64 // R/_
-#define ME6000_AO_01_IRQ_RESET_REG 0x68 // R/_
-#define ME6000_AO_02_IRQ_RESET_REG 0x6C // R/_
-#define ME6000_AO_03_IRQ_RESET_REG 0x70 // R/_
-
-#define ME6000_IRQ_STATUS_BIT_0 0x01
-#define ME6000_IRQ_STATUS_BIT_1 0x02
-#define ME6000_IRQ_STATUS_BIT_2 0x04
-#define ME6000_IRQ_STATUS_BIT_3 0x08
-
-#define ME6000_IRQ_STATUS_BIT_AO_HF ME6000_IRQ_STATUS_BIT_0
-
-//DUMY register
-#define ME6000_AO_DUMY 0xFC
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me6000_device.c b/drivers/staging/meilhaus/me6000_device.c
deleted file mode 100644
index 1a6cf7f..0000000
--- a/drivers/staging/meilhaus/me6000_device.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * @file me6000_device.c
- *
- * @brief Device class template implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#ifndef MODULE
-# define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "mefirmware.h"
-
-#include "mesubdevice.h"
-#include "medebug.h"
-#include "medevice.h"
-#include "me6000_reg.h"
-#include "me6000_device.h"
-#include "meplx_reg.h"
-#include "me6000_dio.h"
-#include "me6000_ao.h"
-
-/**
- * @brief Global variable.
- * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts).
- */
-static struct workqueue_struct *me6000_workqueue;
-
-me_device_t *me6000_pci_constructor(struct pci_dev *pci_device)
-{
- me6000_device_t *me6000_device;
- me_subdevice_t *subdevice;
- unsigned int version_idx;
- int err;
- int i;
- int high_range = 0;
- int fifo;
-
- PDEBUG("executed.\n");
-
- // Allocate structure for device instance.
- me6000_device = kmalloc(sizeof(me6000_device_t), GFP_KERNEL);
-
- if (!me6000_device) {
- PERROR("Cannot get memory for device instance.\n");
- return NULL;
- }
-
- memset(me6000_device, 0, sizeof(me6000_device_t));
-
- // Initialize base class structure.
- err = me_device_pci_init((me_device_t *) me6000_device, pci_device);
-
- if (err) {
- kfree(me6000_device);
- PERROR("Cannot initialize device base class.\n");
- return NULL;
- }
-
- /* Download the xilinx firmware */
- err = me_xilinx_download(me6000_device->base.info.pci.reg_bases[1],
- me6000_device->base.info.pci.reg_bases[2],
- &pci_device->dev, "me6000.bin");
-
- if (err) {
- me_device_deinit((me_device_t *) me6000_device);
- kfree(me6000_device);
- PERROR("Can't download firmware.\n");
- return NULL;
- }
-
- /* Get the index in the device version information table. */
- version_idx =
- me6000_versions_get_device_index(me6000_device->base.info.pci.
- device_id);
-
- // Initialize spin lock .
- spin_lock_init(&me6000_device->preload_reg_lock);
- spin_lock_init(&me6000_device->dio_ctrl_reg_lock);
-
- /* Create digital input/output instances. */
- for (i = 0; i < me6000_versions[version_idx].dio_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me6000_dio_constructor(me6000_device->
- base.info.pci.
- reg_bases[3], i,
- &me6000_device->
- dio_ctrl_reg_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me6000_device);
- kfree(me6000_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me6000_device->base.slist,
- subdevice);
- }
-
- /* Create analog output instances. */
- for (i = 0; i < me6000_versions[version_idx].ao_subdevices; i++) {
- high_range = ((i == 8)
- &&
- ((me6000_device->base.info.pci.device_id ==
- PCI_DEVICE_ID_MEILHAUS_ME6359)
- || (me6000_device->base.info.pci.device_id ==
- PCI_DEVICE_ID_MEILHAUS_ME6259)
- )
- )? 1 : 0;
-
- fifo =
- (i <
- me6000_versions[version_idx].
- ao_fifo) ? ME6000_AO_HAS_FIFO : 0x0;
- fifo |= (i < 4) ? ME6000_AO_EXTRA_HARDWARE : 0x0;
-
- subdevice =
- (me_subdevice_t *) me6000_ao_constructor(me6000_device->
- base.info.pci.
- reg_bases[2],
- &me6000_device->
- preload_reg_lock,
- &me6000_device->
- preload_flags,
- &me6000_device->
- triggering_flags,
- i, fifo,
- me6000_device->
- base.irq,
- high_range,
- me6000_workqueue);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me6000_device);
- kfree(me6000_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me6000_device->base.slist,
- subdevice);
- }
-
- return (me_device_t *) me6000_device;
-}
-EXPORT_SYMBOL(me6000_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me6000_init(void)
-{
- PDEBUG("executed.\n");
-
- me6000_workqueue = create_singlethread_workqueue("me6000");
- return 0;
-}
-
-static void __exit me6000_exit(void)
-{
- PDEBUG("executed.\n");
-
- flush_workqueue(me6000_workqueue);
- destroy_workqueue(me6000_workqueue);
-}
-
-module_init(me6000_init);
-module_exit(me6000_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
- ("Guenter Gebhardt <g.gebhardt at meilhaus.de> & Krzysztof Gantzke <k.gantzke at meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for ME-6000 Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-6000 Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me6000_device.h b/drivers/staging/meilhaus/me6000_device.h
deleted file mode 100644
index eed4011..0000000
--- a/drivers/staging/meilhaus/me6000_device.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/**
- * @file me6000_device.h
- *
- * @brief ME-6000 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME6000_DEVICE_H
-#define _ME6000_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-6000 device capabilities.
- */
-typedef struct me6000_version {
- uint16_t device_id;
- unsigned int dio_subdevices;
- unsigned int ao_subdevices;
- unsigned int ao_fifo; //How many devices have FIFO
-} me6000_version_t;
-
-/**
- * @brief ME-6000 device capabilities.
- */
-static me6000_version_t me6000_versions[] = {
- {PCI_DEVICE_ID_MEILHAUS_ME6004, 0, 4, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME6008, 0, 8, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME600F, 0, 16, 0},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6014, 0, 4, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME6018, 0, 8, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME601F, 0, 16, 0},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6034, 0, 4, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME6038, 0, 8, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME603F, 0, 16, 0},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6104, 0, 4, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME6108, 0, 8, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME610F, 0, 16, 4},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6114, 0, 4, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME6118, 0, 8, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME611F, 0, 16, 4},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6134, 0, 4, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME6138, 0, 8, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME613F, 0, 16, 4},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6044, 2, 4, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME6048, 2, 8, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME604F, 2, 16, 0},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6054, 2, 4, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME6058, 2, 8, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME605F, 2, 16, 0},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6074, 2, 4, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME6078, 2, 8, 0},
- {PCI_DEVICE_ID_MEILHAUS_ME607F, 2, 16, 0},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6144, 2, 4, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME6148, 2, 8, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME614F, 2, 16, 4},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6154, 2, 4, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME6158, 2, 8, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME615F, 2, 16, 4},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6174, 2, 4, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME6178, 2, 8, 4},
- {PCI_DEVICE_ID_MEILHAUS_ME617F, 2, 16, 4},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6259, 2, 9, 0},
-
- {PCI_DEVICE_ID_MEILHAUS_ME6359, 2, 9, 4},
-
- {0},
-};
-
-#define ME6000_DEVICE_VERSIONS (ARRAY_SIZE(me6000_versions) - 1) /**< Returns the number of entries in #me6000_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me6000_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me6000_versions.
- */
-static inline unsigned int me6000_versions_get_device_index(uint16_t device_id)
-{
- unsigned int i;
- for (i = 0; i < ME6000_DEVICE_VERSIONS; i++)
- if (me6000_versions[i].device_id == device_id)
- break;
- return i;
-}
-
-/**
- * @brief The ME-6000 device class structure.
- */
-typedef struct me6000_device {
- me_device_t base; /**< The Meilhaus device base class. */
-
- /* Child class attributes. */
- spinlock_t preload_reg_lock; /**< Guards the preload register. */
- uint32_t preload_flags;
- uint32_t triggering_flags;
-
- spinlock_t dio_ctrl_reg_lock;
-} me6000_device_t;
-
-/**
- * @brief The ME-6000 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-6000 device instance. \n
- * NULL on error.
- */
-me_device_t *me6000_pci_constructor(struct pci_dev *pci_device)
- __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me6000_dio.c b/drivers/staging/meilhaus/me6000_dio.c
deleted file mode 100644
index c90686e..0000000
--- a/drivers/staging/meilhaus/me6000_dio.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/**
- * @file me6000_dio.c
- *
- * @brief ME-6000 digital input/output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me6000_dio_reg.h"
-#include "me6000_dio.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me6000_dio_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me6000_dio_subdevice_t *instance;
- uint8_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me6000_dio_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inb(instance->ctrl_reg);
- mode &= ~(0x3 << (instance->dio_idx * 2));
- outb(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- spin_unlock(instance->ctrl_reg_lock);
-
- outb(0x00, instance->port_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, 0x00);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_dio_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me6000_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t mode;
- int size =
- flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
- | ME_IO_SINGLE_CONFIG_DIO_WORD |
- ME_IO_SINGLE_CONFIG_DIO_DWORD);
-
- PDEBUG("executed.\n");
-
- instance = (me6000_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inb(instance->ctrl_reg);
- switch (size) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_BYTE:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
- mode &=
- ~((ME6000_DIO_CTRL_BIT_MODE_0 |
- ME6000_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
- mode &=
- ~((ME6000_DIO_CTRL_BIT_MODE_0 |
- ME6000_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- mode |=
- ME6000_DIO_CTRL_BIT_MODE_0 << (instance->
- dio_idx * 2);
- } else {
- PERROR
- ("Invalid port configuration specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- if (!err) {
- outb(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_dio_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me6000_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me6000_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
- ME6000_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- if ((mode ==
- (ME6000_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) || !mode) {
- *value =
- inb(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
- ME6000_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- if ((mode ==
- (ME6000_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) || !mode) {
- *value = inb(instance->port_reg) & 0x00FF;
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_dio_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me6000_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t mode;
- uint8_t byte;
-
- PDEBUG("executed.\n");
-
- instance = (me6000_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
- ME6000_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
-
- if (mode ==
- (ME6000_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) {
- byte = inb(instance->port_reg) & 0x00FF;
-
- if (value)
- byte |= 0x1 << channel;
- else
- byte &= ~(0x1 << channel);
-
- outb(byte, instance->port_reg);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
- ME6000_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
-
- if (mode ==
- (ME6000_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) {
- outb(value, instance->port_reg);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me6000_dio_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_dio_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DIO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_dio_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_DIO_DIR_BYTE;
- return ME_ERRNO_SUCCESS;
-}
-
-me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base,
- unsigned int dio_idx,
- spinlock_t *ctrl_reg_lock)
-{
- me6000_dio_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me6000_dio_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me6000_dio_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
-
- /* Set the subdevice ports */
- subdevice->ctrl_reg = reg_base + ME6000_DIO_CTRL_REG;
- switch (dio_idx) {
- case 0:
- subdevice->port_reg = reg_base + ME6000_DIO_PORT_0_REG;
- break;
- case 1:
- subdevice->port_reg = reg_base + ME6000_DIO_PORT_1_REG;
- break;
- default:
- err = ME_ERRNO_INVALID_SUBDEVICE;
- }
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Save digital i/o index */
- subdevice->dio_idx = dio_idx;
-
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me6000_dio_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me6000_dio_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me6000_dio_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me6000_dio_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me6000_dio_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me6000_dio_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me6000_dio_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me6000_dio.h b/drivers/staging/meilhaus/me6000_dio.h
deleted file mode 100644
index 858bec1..0000000
--- a/drivers/staging/meilhaus/me6000_dio.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file me6000_dio.h
- *
- * @brief ME-6000 digital input/output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME6000_DIO_H_
-#define _ME6000_DIO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me6000_dio_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
- unsigned int dio_idx; /**< The index of the digital i/o on the device. */
-
- unsigned long port_reg; /**< Register holding the port status. */
- unsigned long ctrl_reg; /**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me6000_dio_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-6000 digital input/ouput subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param dio_idx The index of the digital i/o port on the device.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base,
- unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me6000_dio_reg.h b/drivers/staging/meilhaus/me6000_dio_reg.h
deleted file mode 100644
index e67a791..0000000
--- a/drivers/staging/meilhaus/me6000_dio_reg.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file me6000_dio_reg.h
- *
- * @brief ME-6000 digital input/output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME6000_DIO_REG_H_
-#define _ME6000_DIO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME6000_DIO_CTRL_REG 0x00 // R/W
-#define ME6000_DIO_PORT_0_REG 0x01 // R/W
-#define ME6000_DIO_PORT_1_REG 0x02 // R/W
-#define ME6000_DIO_PORT_REG ME6000_DIO_PORT_0_REG // R/W
-
-#define ME6000_DIO_CTRL_BIT_MODE_0 0x01
-#define ME6000_DIO_CTRL_BIT_MODE_1 0x02
-#define ME6000_DIO_CTRL_BIT_MODE_2 0x04
-#define ME6000_DIO_CTRL_BIT_MODE_3 0x08
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me6000_reg.h b/drivers/staging/meilhaus/me6000_reg.h
deleted file mode 100644
index d352730..0000000
--- a/drivers/staging/meilhaus/me6000_reg.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file me6000_reg.h
- *
- * @brief ME-6000 device register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME6000_REG_H_
-#define _ME6000_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME6000_INIT_XILINX_REG 0xAC // R/-
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_device.c b/drivers/staging/meilhaus/me8100_device.c
deleted file mode 100644
index 41a9345..0000000
--- a/drivers/staging/meilhaus/me8100_device.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * @file me8100_device.c
- *
- * @brief ME-8100 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#ifndef MODULE
-# define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "me8100_device.h"
-#include "mesubdevice.h"
-#include "me8100_di.h"
-#include "me8100_do.h"
-#include "me8254.h"
-
-me_device_t *me8100_pci_constructor(struct pci_dev *pci_device)
-{
- me8100_device_t *me8100_device;
- me_subdevice_t *subdevice;
- unsigned int version_idx;
- int err;
- int i;
-
- PDEBUG("executed.\n");
-
- // Allocate structure for device instance.
- me8100_device = kmalloc(sizeof(me8100_device_t), GFP_KERNEL);
-
- if (!me8100_device) {
- PERROR("Cannot get memory for device instance.\n");
- return NULL;
- }
-
- memset(me8100_device, 0, sizeof(me8100_device_t));
-
- // Initialize base class structure.
- err = me_device_pci_init((me_device_t *) me8100_device, pci_device);
-
- if (err) {
- kfree(me8100_device);
- PERROR("Cannot initialize device base class.\n");
- return NULL;
- }
-
- /* Get the index in the device version information table. */
- version_idx =
- me8100_versions_get_device_index(me8100_device->base.info.pci.
- device_id);
-
- // Initialize spin lock .
- spin_lock_init(&me8100_device->dio_ctrl_reg_lock);
- spin_lock_init(&me8100_device->ctr_ctrl_reg_lock);
- spin_lock_init(&me8100_device->clk_src_reg_lock);
-
- // Create subdevice instances.
-
- for (i = 0; i < me8100_versions[version_idx].di_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me8100_di_constructor(me8100_device->
- base.info.pci.
- reg_bases[2],
- me8100_device->
- base.info.pci.
- reg_bases[1], i,
- me8100_device->
- base.irq,
- &me8100_device->
- dio_ctrl_reg_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me8100_device);
- kfree(me8100_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me8100_device->base.slist,
- subdevice);
- }
-
- for (i = 0; i < me8100_versions[version_idx].do_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me8100_do_constructor(me8100_device->
- base.info.pci.
- reg_bases[2], i,
- &me8100_device->
- dio_ctrl_reg_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me8100_device);
- kfree(me8100_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me8100_device->base.slist,
- subdevice);
- }
-
- for (i = 0; i < me8100_versions[version_idx].ctr_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me8254_constructor(me8100_device->base.
- info.pci.device_id,
- me8100_device->base.
- info.pci.reg_bases[2],
- 0, i,
- &me8100_device->
- ctr_ctrl_reg_lock,
- &me8100_device->
- clk_src_reg_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me8100_device);
- kfree(me8100_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me8100_device->base.slist,
- subdevice);
- }
-
- return (me_device_t *) me8100_device;
-}
-EXPORT_SYMBOL(me8100_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me8100_init(void)
-{
- PDEBUG("executed.\n.");
- return ME_ERRNO_SUCCESS;
-}
-
-static void __exit me8100_exit(void)
-{
- PDEBUG("executed.\n.");
-}
-
-module_init(me8100_init);
-
-module_exit(me8100_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt at meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for Template Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me8100_device.h b/drivers/staging/meilhaus/me8100_device.h
deleted file mode 100644
index 238dc06..0000000
--- a/drivers/staging/meilhaus/me8100_device.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file me8100_device.h
- *
- * @brief ME-8100 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8100_DEVICE_H
-#define _ME8100_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-8100 device capabilities.
- */
-typedef struct me8100_version {
- uint16_t device_id;
- unsigned int di_subdevices;
- unsigned int do_subdevices;
- unsigned int ctr_subdevices;
-} me8100_version_t;
-
-/**
- * @brief Device capabilities.
- */
-static me8100_version_t me8100_versions[] = {
- {PCI_DEVICE_ID_MEILHAUS_ME8100_A, 1, 1, 3},
- {PCI_DEVICE_ID_MEILHAUS_ME8100_B, 2, 2, 3},
- {0},
-};
-
-#define ME8100_DEVICE_VERSIONS (ARRAY_SIZE(me8100_versions) - 1) /**< Returns the number of entries in #me8100_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me8100_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me8100_versions.
- */
-static inline unsigned int me8100_versions_get_device_index(uint16_t device_id)
-{
- unsigned int i;
- for (i = 0; i < ME8100_DEVICE_VERSIONS; i++)
- if (me8100_versions[i].device_id == device_id)
- break;
- return i;
-}
-
-/**
- * @brief The ME-8100 device class structure.
- */
-typedef struct me8100_device {
- me_device_t base; /**< The Meilhaus device base class. */
-
- /* Child class attributes. */
- spinlock_t dio_ctrl_reg_lock;
- spinlock_t ctr_ctrl_reg_lock;
- spinlock_t clk_src_reg_lock;
-} me8100_device_t;
-
-/**
- * @brief The ME-8100 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-8100 device instance. \n
- * NULL on error.
- */
-me_device_t *me8100_pci_constructor(struct pci_dev *pci_device)
- __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_di.c b/drivers/staging/meilhaus/me8100_di.c
deleted file mode 100644
index 1a3f269..0000000
--- a/drivers/staging/meilhaus/me8100_di.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/**
- * @file me8100_di.c
- *
- * @brief ME-8100 digital input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-#include "medefines.h"
-#include "meerror.h"
-
-#include "meids.h"
-#include "medebug.h"
-#include "meplx_reg.h"
-#include "me8100_reg.h"
-#include "me8100_di_reg.h"
-#include "me8100_di.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me8100_di_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me8100_di_subdevice_t *instance;
- unsigned short ctrl;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_di_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- spin_lock(instance->ctrl_reg_lock);
- ctrl = inw(instance->ctrl_reg);
- ctrl &= ~(ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0);
- outw(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock(instance->ctrl_reg_lock);
-
- outw(0, instance->mask_reg);
- PDEBUG_REG("mask_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->mask_reg - instance->reg_base, 0);
- outw(0, instance->pattern_reg);
- PDEBUG_REG("pattern_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->pattern_reg - instance->reg_base, 0);
- instance->rised = -1;
- instance->irq_count = 0;
- instance->filtering_flag = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- outl(PLX_INTCSR_LOCAL_INT1_EN |
- PLX_INTCSR_LOCAL_INT1_POL |
- PLX_INTCSR_LOCAL_INT2_EN |
- PLX_INTCSR_LOCAL_INT2_POL |
- PLX_INTCSR_PCI_INT_EN, instance->irq_status_reg);
- PDEBUG_REG("plx:irq_status_reg outl(0x%lX)=0x%x\n",
- instance->irq_status_reg,
- PLX_INTCSR_LOCAL_INT1_EN | PLX_INTCSR_LOCAL_INT1_POL |
- PLX_INTCSR_LOCAL_INT2_EN | PLX_INTCSR_LOCAL_INT2_POL |
- PLX_INTCSR_PCI_INT_EN);
-
- wake_up_interruptible_all(&instance->wait_queue);
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_di_io_irq_start(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int irq_source,
- int irq_edge, int irq_arg, int flags)
-{
- me8100_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint16_t ctrl;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_di_subdevice_t *) subdevice;
-
- if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
- if (flags &
- ~(ME_IO_IRQ_START_PATTERN_FILTERING |
- ME_IO_IRQ_START_DIO_WORD)) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (irq_edge != ME_IRQ_EDGE_NOT_USED) {
- PERROR("Invalid irq edge specified.\n");
- return ME_ERRNO_INVALID_IRQ_EDGE;
- }
- } else if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
- if (flags &
- ~(ME_IO_IRQ_START_EXTENDED_STATUS |
- ME_IO_IRQ_START_DIO_WORD)) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (irq_edge != ME_IRQ_EDGE_ANY) {
- PERROR("Invalid irq edge specified.\n");
- return ME_ERRNO_INVALID_IRQ_EDGE;
- }
-
- if (!(irq_arg & 0xFFFF)) {
- PERROR("No mask specified.\n");
- return ME_ERRNO_INVALID_IRQ_ARG;
- }
- } else {
- PERROR("Invalid irq source specified.\n");
- return ME_ERRNO_INVALID_IRQ_SOURCE;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
- outw(irq_arg, instance->pattern_reg);
- instance->compare_value = irq_arg;
- instance->filtering_flag =
- (flags & ME_IO_IRQ_START_PATTERN_FILTERING) ? 1 : 0;
- }
- if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
- outw(irq_arg, instance->mask_reg);
- }
-
- spin_lock(instance->ctrl_reg_lock);
- ctrl = inw(instance->ctrl_reg);
- ctrl |= ME8100_DIO_CTRL_BIT_INTB_0;
- if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
- ctrl &= ~ME8100_DIO_CTRL_BIT_INTB_1;
- }
-
- if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
- ctrl |= ME8100_DIO_CTRL_BIT_INTB_1;
- }
- outw(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock(instance->ctrl_reg_lock);
-
- instance->rised = 0;
- instance->status_value = 0;
- instance->status_value_edges = 0;
- instance->line_value = inw(instance->port_reg);
- instance->status_flag = flags & ME_IO_IRQ_START_EXTENDED_STATUS;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8100_di_io_irq_wait(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *irq_count,
- int *value, int time_out, int flags)
-{
- me8100_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- long t = 0;
- unsigned long cpu_flags;
- int count;
-
- PDEBUG("executed.\n");
- PDEVELOP("PID: %d.\n", current->pid);
-
- instance = (me8100_di_subdevice_t *) subdevice;
-
- if (flags &
- ~(ME_IO_IRQ_WAIT_NORMAL_STATUS | ME_IO_IRQ_WAIT_EXTENDED_STATUS)) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (time_out < 0) {
- PERROR("Invalid time_out specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- t = (time_out * HZ) / 1000;
-
- if (t == 0)
- t = 1;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (instance->rised <= 0) {
- instance->rised = 0;
- count = instance->irq_count;
-
- if (time_out) {
- t = wait_event_interruptible_timeout(instance->
- wait_queue,
- ((count !=
- instance->
- irq_count)
- || (instance->
- rised < 0)),
- t);
-// t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t);
- if (t == 0) {
- PERROR("Wait on interrupt timed out.\n");
- err = ME_ERRNO_TIMEOUT;
- }
- } else {
- wait_event_interruptible(instance->wait_queue,
- ((count != instance->irq_count)
- || (instance->rised < 0)));
-// wait_event_interruptible(instance->wait_queue, (instance->rised != 0));
- }
-
- if (instance->rised < 0) {
- PERROR("Wait on interrupt aborted by user.\n");
- err = ME_ERRNO_CANCELLED;
- }
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on interrupt aborted by signal.\n");
- err = ME_ERRNO_SIGNAL;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- *irq_count = instance->irq_count;
- if (!err) {
- if (flags & ME_IO_IRQ_WAIT_NORMAL_STATUS) {
- *value = instance->status_value;
- } else if (flags & ME_IO_IRQ_WAIT_EXTENDED_STATUS) {
- *value = instance->status_value_edges;
- } else { // Use default
- if (!instance->status_flag) {
- *value = instance->status_value;
- } else {
- *value = instance->status_value_edges;
- }
- }
- instance->rised = 0;
-/*
- instance->status_value = 0;
- instance->status_value_edges = 0;
-*/
- } else {
- *value = 0;
- }
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8100_di_io_irq_stop(me_subdevice_t *subdevice,
- struct file *filep, int channel, int flags)
-{
- me8100_di_subdevice_t *instance;
- uint16_t ctrl;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_di_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- spin_lock(instance->ctrl_reg_lock);
- ctrl = inw(instance->ctrl_reg);
- ctrl &= ~(ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0);
- outw(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock(instance->ctrl_reg_lock);
- instance->rised = -1;
- instance->status_value = 0;
- instance->status_value_edges = 0;
- instance->filtering_flag = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_di_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me8100_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_di_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
-
- switch (flags) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_WORD:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
- } else {
- PERROR
- ("Invalid port configuration specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8100_di_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me8100_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_di_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
-
- switch (flags) {
-
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 16)) {
- *value = inw(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = inw(instance->port_reg) & 0xFF;
- } else if (channel == 1) {
- *value = (inw(instance->port_reg) >> 8) & 0xFF;
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_WORD:
- if (channel == 0) {
- *value = inw(instance->port_reg);
- } else {
- PERROR("Invalid word number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8100_di_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 16;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_di_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DI;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_DIO_BIT_PATTERN_IRQ | ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY;
- return ME_ERRNO_SUCCESS;
-}
-
-static void me8100_di_destructor(struct me_subdevice *subdevice)
-{
- me8100_di_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_di_subdevice_t *) subdevice;
-
- free_irq(instance->irq, (void *)instance);
- me_subdevice_deinit(&instance->base);
- kfree(instance);
-}
-
-static irqreturn_t me8100_isr(int irq, void *dev_id)
-{
- me8100_di_subdevice_t *instance;
- uint32_t icsr;
-
- uint16_t irq_status;
- uint16_t line_value = 0;
-
- uint32_t status_val = 0;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_di_subdevice_t *) dev_id;
-
- if (irq != instance->irq) {
- PERROR("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- icsr = inl(instance->irq_status_reg);
- if (instance->di_idx == 0) {
-
- if ((icsr &
- (PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_PCI_INT_EN |
- PLX_INTCSR_LOCAL_INT1_EN)) !=
- (PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_PCI_INT_EN |
- PLX_INTCSR_LOCAL_INT1_EN)) {
- PINFO
- ("%ld Shared interrupt. %s(): idx=0 plx:irq_status_reg=0x%04X\n",
- jiffies, __func__, icsr);
- return IRQ_NONE;
- }
- } else if (instance->di_idx == 1) {
- if ((icsr &
- (PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_PCI_INT_EN |
- PLX_INTCSR_LOCAL_INT2_EN)) !=
- (PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_PCI_INT_EN |
- PLX_INTCSR_LOCAL_INT2_EN)) {
- PINFO
- ("%ld Shared interrupt. %s(): idx=1 plx:irq_status_reg=0x%04X\n",
- jiffies, __func__, icsr);
- return IRQ_NONE;
- }
- } else {
- PERROR("%s():Wrong interrupt idx=%d csr=0x%X.\n", __func__,
- instance->di_idx, icsr);
- return IRQ_NONE;
- }
-
- PDEBUG("me8100_isr():Interrupt from idx=%d occured.\n",
- instance->di_idx);
- spin_lock(&instance->subdevice_lock);
- inw(instance->irq_reset_reg);
- line_value = inw(instance->port_reg);
-
- irq_status = instance->line_value ^ line_value;
-
- // Make extended information.
- status_val |= (0x00FF & (~(uint16_t) instance->line_value & line_value)) << 16; //Raise
- status_val |= (0x00FF & ((uint16_t) instance->line_value & ~line_value)); //Fall
-
- instance->line_value = line_value;
-
- if (instance->rised == 0) {
- instance->status_value = irq_status;
- instance->status_value_edges = status_val;
- } else {
- instance->status_value |= irq_status;
- instance->status_value_edges |= status_val;
- }
-
- if (instance->filtering_flag) { // For compare mode only.
- if (instance->compare_value == instance->line_value) {
- instance->rised = 1;
- instance->irq_count++;
- }
- } else {
- instance->rised = 1;
- instance->irq_count++;
- }
-
- spin_unlock(&instance->subdevice_lock);
- wake_up_interruptible_all(&instance->wait_queue);
-
- return IRQ_HANDLED;
-}
-
-me8100_di_subdevice_t *me8100_di_constructor(uint32_t me8100_reg_base,
- uint32_t plx_reg_base,
- unsigned int di_idx,
- int irq,
- spinlock_t *ctrl_reg_lock)
-{
- me8100_di_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me8100_di_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me8100_di_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Save the subdevice index. */
- subdevice->di_idx = di_idx;
-
- /* Initialize wait queue */
- init_waitqueue_head(&subdevice->wait_queue);
-
- /* Register interrupt service routine. */
- subdevice->irq = irq;
- err = request_irq(subdevice->irq, me8100_isr,
- IRQF_DISABLED | IRQF_SHARED,
- ME8100_NAME, (void *)subdevice);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- PINFO("Registered irq=%d.\n", subdevice->irq);
-
- /* Initialize the registers */
- subdevice->ctrl_reg =
- me8100_reg_base + ME8100_CTRL_REG_A + di_idx * ME8100_REG_OFFSET;
- subdevice->port_reg =
- me8100_reg_base + ME8100_DI_REG_A + di_idx * ME8100_REG_OFFSET;
- subdevice->mask_reg =
- me8100_reg_base + ME8100_MASK_REG_A + di_idx * ME8100_REG_OFFSET;
- subdevice->pattern_reg =
- me8100_reg_base + ME8100_PATTERN_REG_A + di_idx * ME8100_REG_OFFSET;
- subdevice->din_int_reg =
- me8100_reg_base + ME8100_INT_DI_REG_A + di_idx * ME8100_REG_OFFSET;
- subdevice->irq_reset_reg =
- me8100_reg_base + ME8100_RES_INT_REG_A + di_idx * ME8100_REG_OFFSET;
- subdevice->irq_status_reg = plx_reg_base + PLX_INTCSR;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = me8100_reg_base;
-#endif
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_irq_start = me8100_di_io_irq_start;
- subdevice->base.me_subdevice_io_irq_wait = me8100_di_io_irq_wait;
- subdevice->base.me_subdevice_io_irq_stop = me8100_di_io_irq_stop;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me8100_di_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me8100_di_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me8100_di_io_single_read;
- subdevice->base.me_subdevice_query_number_channels =
- me8100_di_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me8100_di_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me8100_di_query_subdevice_caps;
- subdevice->base.me_subdevice_destructor = me8100_di_destructor;
-
- subdevice->rised = 0;
- subdevice->irq_count = 0;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8100_di.h b/drivers/staging/meilhaus/me8100_di.h
deleted file mode 100644
index e1db791..0000000
--- a/drivers/staging/meilhaus/me8100_di.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @file me8100_di.h
- *
- * @brief ME-8100 digital input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8100_DI_H_
-#define _ME8100_DI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me8100_di_subdevice {
- // Inheritance
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock;
-
- unsigned di_idx;
-
- int irq;
- volatile int rised;
- unsigned int irq_count;
-
- uint status_flag; /**< Default interupt status flag */
- uint status_value; /**< Interupt status */
- uint status_value_edges; /**< Extended interupt status */
- uint line_value;
-
- uint16_t compare_value;
- uint8_t filtering_flag;
-
- wait_queue_head_t wait_queue;
-
- unsigned long ctrl_reg;
- unsigned long port_reg;
- unsigned long mask_reg;
- unsigned long pattern_reg;
- unsigned long long din_int_reg;
- unsigned long irq_reset_reg;
- unsigned long irq_status_reg;
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-
-} me8100_di_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-8100 digital input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8100_di_subdevice_t *me8100_di_constructor(uint32_t me8100_reg_base,
- uint32_t plx_reg_base,
- unsigned int di_idx,
- int irq,
- spinlock_t * ctrl_leg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_di_reg.h b/drivers/staging/meilhaus/me8100_di_reg.h
deleted file mode 100644
index 063bd19..0000000
--- a/drivers/staging/meilhaus/me8100_di_reg.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * @file me8100_di_reg.h
- *
- * @brief ME-8100 digital input subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8100_DI_REG_H_
-#define _ME8100_DI_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8100_RES_INT_REG_A 0x02 //(r, )
-#define ME8100_DI_REG_A 0x04 //(r, )
-#define ME8100_PATTERN_REG_A 0x08 //( ,w)
-#define ME8100_MASK_REG_A 0x0A //( ,w)
-#define ME8100_INT_DI_REG_A 0x0A //(r, )
-
-#define ME8100_RES_INT_REG_B 0x0E //(r, )
-#define ME8100_DI_REG_B 0x10 //(r, )
-#define ME8100_PATTERN_REG_B 0x14 //( ,w)
-#define ME8100_MASK_REG_B 0x16 //( ,w)
-#define ME8100_INT_DI_REG_B 0x16 //(r, )
-
-#define ME8100_REG_OFFSET 0x0C
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_do.c b/drivers/staging/meilhaus/me8100_do.c
deleted file mode 100644
index 81651a9..0000000
--- a/drivers/staging/meilhaus/me8100_do.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/**
- * @file me8100_do.c
- *
- * @brief ME-8100 digital output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me8100_reg.h"
-#include "me8100_do_reg.h"
-#include "me8100_do.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me8100_do_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me8100_do_subdevice_t *instance;
- uint16_t ctrl;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_do_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- ctrl = inw(instance->ctrl_reg);
- ctrl &= ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0;
- outw(ctrl, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, ctrl);
- spin_unlock(instance->ctrl_reg_lock);
- outw(0, instance->port_reg);
- instance->port_reg_mirror = 0;
- PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->port_reg - instance->reg_base, 0);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_do_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me8100_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- int config;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- config = inw(instance->ctrl_reg);
- switch (flags) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_WORD:
- if (channel == 0) {
- if (single_config ==
- ME_SINGLE_CONFIG_DIO_HIGH_IMPEDANCE) {
- config &= ~(ME8100_DIO_CTRL_BIT_ENABLE_DIO);
- } else if (single_config == ME_SINGLE_CONFIG_DIO_SINK) {
- config |= ME8100_DIO_CTRL_BIT_ENABLE_DIO;
- config &= ~ME8100_DIO_CTRL_BIT_SOURCE;
- } else if (single_config == ME_SINGLE_CONFIG_DIO_SOURCE) {
- config |=
- ME8100_DIO_CTRL_BIT_ENABLE_DIO |
- ME8100_DIO_CTRL_BIT_SOURCE;
- } else {
- PERROR
- ("Invalid port configuration specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid word number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- if (!err) {
- outw(config, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, config);
- }
-
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8100_do_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me8100_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 16)) {
- *value = instance->port_reg_mirror & (0x1 << channel);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = instance->port_reg_mirror & 0xFF;
- } else if (channel == 1) {
- *value = (instance->port_reg_mirror >> 8) & 0xFF;
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_WORD:
- if (channel == 0) {
- *value = instance->port_reg_mirror;
- } else {
- PERROR("Invalid word number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8100_do_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me8100_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me8100_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 16)) {
- instance->port_reg_mirror =
- value ? (instance->
- port_reg_mirror | (0x1 << channel))
- : (instance->port_reg_mirror & ~(0x1 << channel));
- outw(instance->port_reg_mirror, instance->port_reg);
- PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg - instance->reg_base,
- instance->port_reg_mirror);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- instance->port_reg_mirror &= ~0xFF;
- instance->port_reg_mirror |= value & 0xFF;
- outw(instance->port_reg_mirror, instance->port_reg);
- PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg - instance->reg_base,
- instance->port_reg_mirror);
- } else if (channel == 1) {
- instance->port_reg_mirror &= ~0xFF00;
- instance->port_reg_mirror |= (value << 8) & 0xFF00;
- outw(instance->port_reg_mirror, instance->port_reg);
- PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg - instance->reg_base,
- instance->port_reg_mirror);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_WORD:
- if (channel == 0) {
- instance->port_reg_mirror = value;
- outw(value, instance->port_reg);
- PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg - instance->reg_base,
- value);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8100_do_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 16;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_do_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_DIO_SINK_SOURCE;
- return ME_ERRNO_SUCCESS;
-}
-
-me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base,
- unsigned int do_idx,
- spinlock_t *ctrl_reg_lock)
-{
- me8100_do_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me8100_do_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me8100_do_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
-
- /* Initialize registers */
- if (do_idx == 0) {
- subdevice->port_reg = reg_base + ME8100_DO_REG_A;
- subdevice->ctrl_reg = reg_base + ME8100_CTRL_REG_A;
- } else if (do_idx == 1) {
- subdevice->port_reg = reg_base + ME8100_DO_REG_B;
- subdevice->ctrl_reg = reg_base + ME8100_CTRL_REG_B;
- } else {
- PERROR("Wrong subdevice idx=%d.\n", do_idx);
- kfree(subdevice);
- return NULL;
- }
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Save the subdevice index */
- subdevice->do_idx = do_idx;
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me8100_do_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me8100_do_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me8100_do_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me8100_do_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me8100_do_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me8100_do_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me8100_do_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8100_do.h b/drivers/staging/meilhaus/me8100_do.h
deleted file mode 100644
index acf8801..0000000
--- a/drivers/staging/meilhaus/me8100_do.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file me8100_do.h
- *
- * @brief ME-8100 digital output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8100_DO_H_
-#define _ME8100_DO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me8100_do_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect the #ctrl_reg. */
-
- unsigned int do_idx;
-
- uint16_t port_reg_mirror; /**< Mirror used to store current port register setting which is write only. */
-
- unsigned long port_reg; /**< Register holding the port status. */
- unsigned long ctrl_reg; /**< Control register. */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me8100_do_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-8100 digital output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param do_idx The index of the digital output subdevice on this device.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base,
- unsigned int do_idx,
- spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_do_reg.h b/drivers/staging/meilhaus/me8100_do_reg.h
deleted file mode 100644
index 13a2380..0000000
--- a/drivers/staging/meilhaus/me8100_do_reg.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @file me8100_ao_reg.h
- *
- * @brief ME-8100 analog output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8100_DO_REG_H_
-#define _ME8100_DO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8100_DO_REG_A 0x06 //( ,w)
-#define ME8100_DO_REG_B 0x12 //( ,w)
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_reg.h b/drivers/staging/meilhaus/me8100_reg.h
deleted file mode 100644
index d8c4b1c..0000000
--- a/drivers/staging/meilhaus/me8100_reg.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file me8100_reg.h
- *
- * @brief ME-8100 register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8100_REG_H_
-#define _ME8100_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8100_CTRL_REG_A 0x00 //( ,w)
-#define ME8100_CTRL_REG_B 0x0C //( ,w)
-
-#define ME8100_DIO_CTRL_BIT_SOURCE 0x10
-#define ME8100_DIO_CTRL_BIT_INTB_1 0x20
-#define ME8100_DIO_CTRL_BIT_INTB_0 0x40
-#define ME8100_DIO_CTRL_BIT_ENABLE_DIO 0x80
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_device.c b/drivers/staging/meilhaus/me8200_device.c
deleted file mode 100644
index b313679..0000000
--- a/drivers/staging/meilhaus/me8200_device.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/**
- * @file me8200_device.c
- *
- * @brief ME-8200 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#ifndef MODULE
-# define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "meplx_reg.h"
-#include "medevice.h"
-#include "me8200_device.h"
-#include "mesubdevice.h"
-#include "me8200_di.h"
-#include "me8200_do.h"
-#include "me8200_dio.h"
-
-me_device_t *me8200_pci_constructor(struct pci_dev *pci_device)
-{
- me8200_device_t *me8200_device;
- me_subdevice_t *subdevice;
- unsigned int version_idx;
- int err;
- int i;
-
- PDEBUG("executed.\n");
-
- // Allocate structure for device instance.
- me8200_device = kmalloc(sizeof(me8200_device_t), GFP_KERNEL);
-
- if (!me8200_device) {
- PERROR("Cannot get memory for device instance.\n");
- return NULL;
- }
-
- memset(me8200_device, 0, sizeof(me8200_device_t));
-
- // Initialize base class structure.
- err = me_device_pci_init((me_device_t *) me8200_device, pci_device);
-
- if (err) {
- kfree(me8200_device);
- PERROR("Cannot initialize device base class.\n");
- return NULL;
- }
-
- /* Get the index in the device version information table. */
- version_idx =
- me8200_versions_get_device_index(me8200_device->base.info.pci.
- device_id);
-
- // Initialize spin lock .
- spin_lock_init(&me8200_device->irq_ctrl_lock);
- spin_lock_init(&me8200_device->irq_mode_lock);
- spin_lock_init(&me8200_device->dio_ctrl_lock);
-
- /* Setup the PLX interrupt configuration */
- outl(PLX_INTCSR_LOCAL_INT1_EN |
- PLX_INTCSR_LOCAL_INT1_POL |
- PLX_INTCSR_LOCAL_INT2_EN |
- PLX_INTCSR_LOCAL_INT2_POL |
- PLX_INTCSR_PCI_INT_EN,
- me8200_device->base.info.pci.reg_bases[1] + PLX_INTCSR);
-
- // Create subdevice instances.
-
- for (i = 0; i < me8200_versions[version_idx].di_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me8200_di_constructor(me8200_device->
- base.info.pci.
- reg_bases[2], i,
- me8200_device->
- base.irq,
- &me8200_device->
- irq_ctrl_lock,
- &me8200_device->
- irq_mode_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me8200_device);
- kfree(me8200_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me8200_device->base.slist,
- subdevice);
- }
-
- for (i = 0; i < me8200_versions[version_idx].do_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me8200_do_constructor(me8200_device->
- base.info.pci.
- reg_bases[2], i,
- me8200_device->
- base.irq,
- &me8200_device->
- irq_mode_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me8200_device);
- kfree(me8200_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me8200_device->base.slist,
- subdevice);
- }
-
- for (i = 0; i < me8200_versions[version_idx].dio_subdevices; i++) {
- subdevice =
- (me_subdevice_t *) me8200_dio_constructor(me8200_device->
- base.info.pci.
- reg_bases[2], i,
- &me8200_device->
- dio_ctrl_lock);
-
- if (!subdevice) {
- me_device_deinit((me_device_t *) me8200_device);
- kfree(me8200_device);
- PERROR("Cannot get memory for subdevice.\n");
- return NULL;
- }
-
- me_slist_add_subdevice_tail(&me8200_device->base.slist,
- subdevice);
- }
-
- return (me_device_t *) me8200_device;
-}
-EXPORT_SYMBOL(me8200_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me8200_init(void)
-{
- PDEBUG("executed.\n.");
- return 0;
-}
-
-static void __exit me8200_exit(void)
-{
- PDEBUG("executed.\n.");
-}
-
-module_init(me8200_init);
-
-module_exit(me8200_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt at meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for Template Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me8200_device.h b/drivers/staging/meilhaus/me8200_device.h
deleted file mode 100644
index 66f5084..0000000
--- a/drivers/staging/meilhaus/me8200_device.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file me8200_device.h
- *
- * @brief ME-8200 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8200_DEVICE_H
-#define _ME8200_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-8200 device capabilities.
- */
-typedef struct me8200_version {
- uint16_t device_id;
- unsigned int di_subdevices;
- unsigned int do_subdevices;
- unsigned int dio_subdevices;
-} me8200_version_t;
-
-/**
- * @brief Device capabilities.
- */
-static me8200_version_t me8200_versions[] = {
- {PCI_DEVICE_ID_MEILHAUS_ME8200_A, 1, 1, 2},
- {PCI_DEVICE_ID_MEILHAUS_ME8200_B, 2, 2, 2},
- {0},
-};
-
-#define ME8200_DEVICE_VERSIONS (ARRAY_SIZE(me8200_versions) - 1) /**< Returns the number of entries in #me8200_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me8200_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me8200_versions.
- */
-static inline unsigned int me8200_versions_get_device_index(uint16_t device_id)
-{
- unsigned int i;
- for (i = 0; i < ME8200_DEVICE_VERSIONS; i++)
- if (me8200_versions[i].device_id == device_id)
- break;
- return i;
-}
-
-/**
- * @brief The ME-8200 device class structure.
- */
-typedef struct me8200_device {
- me_device_t base; /**< The Meilhaus device base class. */
-
- /* Child class attributes. */
- spinlock_t irq_ctrl_lock; /**< Lock for the interrupt control register. */
- spinlock_t irq_mode_lock; /**< Lock for the interrupt mode register. */
- spinlock_t dio_ctrl_lock; /**< Lock for the digital i/o control register. */
-} me8200_device_t;
-
-/**
- * @brief The ME-8200 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-8200 device instance. \n
- * NULL on error.
- */
-me_device_t *me8200_pci_constructor(struct pci_dev *pci_device)
- __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_di.c b/drivers/staging/meilhaus/me8200_di.c
deleted file mode 100644
index fd1af0f..0000000
--- a/drivers/staging/meilhaus/me8200_di.c
+++ /dev/null
@@ -1,832 +0,0 @@
-/**
- * @file me8200_di.c
- *
- * @brief ME-8200 digital input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-///Includes
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-#include "medefines.h"
-#include "meerror.h"
-
-#include "meids.h"
-#include "medebug.h"
-#include "me8200_reg.h"
-#include "me8200_di_reg.h"
-#include "me8200_di.h"
-
-/// Defines
-static void me8200_di_destructor(struct me_subdevice *subdevice);
-static int me8200_di_io_irq_start(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int irq_source,
- int irq_edge, int irq_arg, int flags);
-static int me8200_di_io_irq_wait(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *irq_count,
- int *value, int time_out, int flags);
-static int me8200_di_io_irq_stop(me_subdevice_t *subdevice,
- struct file *filep, int channel, int flags);
-static int me8200_di_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags);
-static int me8200_di_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags);
-static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags);
-static int me8200_di_query_number_channels(me_subdevice_t *subdevice,
- int *number);
-static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype);
-static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps);
-static irqreturn_t me8200_isr(int irq, void *dev_id);
-static irqreturn_t me8200_isr_EX(int irq, void *dev_id);
-static void me8200_di_check_version(me8200_di_subdevice_t *instance,
- unsigned long addr);
-
-///Functions
-static int me8200_di_io_irq_start(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int irq_source,
- int irq_edge, int irq_arg, int flags)
-{
- me8200_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- volatile uint8_t tmp;
- unsigned long status;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_di_subdevice_t *) subdevice;
-
- if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
- if (flags &
- ~(ME_IO_IRQ_START_PATTERN_FILTERING |
- ME_IO_IRQ_START_DIO_BYTE)) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (irq_edge != ME_IRQ_EDGE_NOT_USED) {
- PERROR("Invalid irq edge specified.\n");
- return ME_ERRNO_INVALID_IRQ_EDGE;
- }
- } else if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
- if (flags &
- ~(ME_IO_IRQ_START_EXTENDED_STATUS |
- ME_IO_IRQ_START_DIO_BYTE)) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if ((irq_edge != ME_IRQ_EDGE_RISING)
- && (irq_edge != ME_IRQ_EDGE_FALLING)
- && (irq_edge != ME_IRQ_EDGE_ANY)) {
- PERROR("Invalid irq edge specified.\n");
- return ME_ERRNO_INVALID_IRQ_EDGE;
- }
-
- if (!(irq_arg & 0xFF)) {
- PERROR("No mask specified.\n");
- return ME_ERRNO_INVALID_IRQ_ARG;
- }
- } else {
- PERROR("Invalid irq source specified.\n");
- return ME_ERRNO_INVALID_IRQ_SOURCE;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, status);
- if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
- outb(irq_arg, instance->compare_reg);
- PDEBUG_REG("compare_reg outb(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->compare_reg - instance->reg_base, irq_arg);
- outb(0xFF, instance->mask_reg);
- PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->mask_reg - instance->reg_base, 0xff);
- instance->compare_value = irq_arg;
- instance->filtering_flag =
- (flags & ME_IO_IRQ_START_PATTERN_FILTERING) ? 1 : 0;
- }
- if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
- outb(irq_arg, instance->mask_reg);
- PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->mask_reg - instance->reg_base, irq_arg);
- instance->filtering_flag = 0;
- }
-
- spin_lock(instance->irq_mode_lock);
- tmp = inb(instance->irq_mode_reg);
- tmp &=
- ~(ME8200_IRQ_MODE_MASK <<
- (ME8200_IRQ_MODE_DI_SHIFT * instance->di_idx));
- if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
- tmp |=
- ME8200_IRQ_MODE_MASK_COMPARE << (ME8200_IRQ_MODE_DI_SHIFT *
- instance->di_idx);
- }
-
- if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
- tmp |=
- ME8200_IRQ_MODE_MASK_MASK << (ME8200_IRQ_MODE_DI_SHIFT *
- instance->di_idx);
- }
- outb(tmp, instance->irq_mode_reg);
- PDEBUG_REG("irq_mode_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_mode_reg - instance->reg_base, tmp);
- spin_unlock(instance->irq_mode_lock);
-
- spin_lock(instance->irq_ctrl_lock);
- tmp = inb(instance->irq_ctrl_reg);
- tmp |=
- (ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
- (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
- tmp |=
- ME8200_DI_IRQ_CTRL_BIT_ENABLE << (ME8200_DI_IRQ_CTRL_SHIFT *
- instance->di_idx);
-
- if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
- tmp &=
- ~(ME8200_DI_IRQ_CTRL_MASK_EDGE <<
- (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
- if (irq_edge == ME_IRQ_EDGE_RISING) {
- tmp |=
- ME8200_DI_IRQ_CTRL_MASK_EDGE_RISING <<
- (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx);
- } else if (irq_edge == ME_IRQ_EDGE_FALLING) {
- tmp |=
- ME8200_DI_IRQ_CTRL_MASK_EDGE_FALLING <<
- (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx);
- } else if (irq_edge == ME_IRQ_EDGE_ANY) {
- tmp |=
- ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY <<
- (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx);
- }
- }
- outb(tmp, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, tmp);
- tmp &=
- ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
- (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
- outb(tmp, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, tmp);
-
- instance->line_value = inb(instance->port_reg);
- spin_unlock(instance->irq_ctrl_lock);
-
- instance->rised = 0;
- instance->status_value = 0;
- instance->status_value_edges = 0;
- instance->status_flag = flags & ME_IO_IRQ_START_EXTENDED_STATUS;
- spin_unlock_irqrestore(&instance->subdevice_lock, status);
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_di_io_irq_wait(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *irq_count,
- int *value, int time_out, int flags)
-{
- me8200_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- long t = 0;
- unsigned long cpu_flags;
- int count;
-
- PDEBUG("executed.\n");
- PDEVELOP("PID: %d.\n", current->pid);
-
- instance = (me8200_di_subdevice_t *) subdevice;
-
- if (flags &
- ~(ME_IO_IRQ_WAIT_NORMAL_STATUS | ME_IO_IRQ_WAIT_EXTENDED_STATUS)) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (time_out < 0) {
- PERROR("Invalid time_out specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- t = (time_out * HZ) / 1000;
-
- if (t == 0)
- t = 1;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (instance->rised <= 0) {
- instance->rised = 0;
- count = instance->count;
-
- if (time_out) {
- t = wait_event_interruptible_timeout(instance->
- wait_queue,
- ((count !=
- instance->count)
- || (instance->
- rised < 0)),
- t);
-// t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t);
- if (t == 0) {
- PERROR("Wait on interrupt timed out.\n");
- err = ME_ERRNO_TIMEOUT;
- }
- } else {
- wait_event_interruptible(instance->wait_queue,
- ((count != instance->count)
- || (instance->rised < 0)));
-// wait_event_interruptible(instance->wait_queue, (instance->rised != 0));
- }
-
- if (instance->rised < 0) {
- PERROR("Wait on interrupt aborted by user.\n");
- err = ME_ERRNO_CANCELLED;
- }
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on interrupt aborted by signal.\n");
- err = ME_ERRNO_SIGNAL;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- *irq_count = instance->count;
- if (!err) {
- if (flags & ME_IO_IRQ_WAIT_NORMAL_STATUS) {
- *value = instance->status_value;
- } else if (flags & ME_IO_IRQ_WAIT_EXTENDED_STATUS) {
- *value = instance->status_value_edges;
- } else { // Use default
- if (!instance->status_flag) {
- *value = instance->status_value;
- } else {
- *value = instance->status_value_edges;
- }
- }
- instance->rised = 0;
-/*
- instance->status_value = 0;
- instance->status_value_edges = 0;
-*/
- } else {
- *value = 0;
- }
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_di_io_irq_stop(me_subdevice_t *subdevice,
- struct file *filep, int channel, int flags)
-{
- me8200_di_subdevice_t *instance;
- uint8_t tmp;
- unsigned long status;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_di_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER spin_lock_irqsave(&instance->subdevice_lock, status);
- spin_lock(instance->irq_ctrl_lock);
- tmp = inb(instance->irq_ctrl_reg);
- tmp |=
- (ME8200_DI_IRQ_CTRL_BIT_ENABLE <<
- (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
- outb(tmp, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, tmp);
- tmp &=
- ~(ME8200_DI_IRQ_CTRL_BIT_ENABLE <<
- (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
- tmp |=
- (ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
- (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
-// tmp &= ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
- outb(tmp, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, tmp);
- spin_unlock(instance->irq_ctrl_lock);
-
- instance->rised = -1;
- instance->status_value = 0;
- instance->status_value_edges = 0;
- instance->filtering_flag = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock, status);
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_di_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me8200_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long status;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_di_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, status);
-
- switch (flags) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_BYTE:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
- } else {
- PERROR("Invalid port direction specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_di_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me8200_di_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long status;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_di_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, status);
-
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- *value = inb(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = inb(instance->port_reg);
- } else {
- PERROR("Invalid channel number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me8200_di_subdevice_t *instance = (me8200_di_subdevice_t *) subdevice;
-
- PDEBUG("executed.\n");
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- instance->count = 0;
- return me8200_di_io_irq_stop(subdevice, filep, 0, 0);
-}
-
-static int me8200_di_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DI;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- PDEBUG("executed.\n");
- *caps =
- ME_CAPS_DIO_BIT_PATTERN_IRQ |
- ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_RISING |
- ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_FALLING |
- ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY;
- return ME_ERRNO_SUCCESS;
-}
-
-static irqreturn_t me8200_isr(int irq, void *dev_id)
-{
- me8200_di_subdevice_t *instance;
- uint8_t ctrl;
- uint8_t irq_status;
- uint8_t line_value = 0;
- uint8_t line_status = 0;
- uint32_t status_val = 0;
-
- instance = (me8200_di_subdevice_t *) dev_id;
-
- if (irq != instance->irq) {
- PERROR("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- irq_status = inb(instance->irq_status_reg);
- if (!irq_status) {
- PINFO
- ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
- jiffies, __func__, instance->di_idx, irq_status);
- return IRQ_NONE;
- }
-
- PDEBUG("executed.\n");
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->irq_ctrl_lock);
- ctrl = inb(instance->irq_ctrl_reg);
- ctrl |=
- ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT *
- instance->di_idx);
- outb(ctrl, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, ctrl);
- ctrl &=
- ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
- (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
- outb(ctrl, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, ctrl);
-
- line_value = inb(instance->port_reg);
- spin_unlock(instance->irq_ctrl_lock);
-
- line_status = ((uint8_t) instance->line_value ^ line_value);
-
- // Make extended information.
- status_val |= (0x00FF & (~(uint8_t) instance->line_value & line_value)) << 16; //Raise
- status_val |= (0x00FF & ((uint8_t) instance->line_value & ~line_value)); //Fall
-
- instance->line_value = (int)line_value;
-
- if (instance->rised == 0) {
- instance->status_value = irq_status | line_status;
- instance->status_value_edges = status_val;
- } else {
- instance->status_value |= irq_status | line_status;
- instance->status_value_edges |= status_val;
- }
-
- if (instance->filtering_flag) { // For compare mode only.
- if (instance->compare_value == instance->line_value) {
- instance->rised = 1;
- instance->count++;
- }
- } else {
- instance->rised = 1;
- instance->count++;
- }
- spin_unlock(&instance->subdevice_lock);
-
- spin_unlock(&instance->subdevice_lock);
-
- wake_up_interruptible_all(&instance->wait_queue);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t me8200_isr_EX(int irq, void *dev_id)
-{
- me8200_di_subdevice_t *instance;
- uint8_t irq_status = 0;
- uint16_t irq_status_EX = 0;
- uint32_t status_val = 0;
- int i, j;
-
- instance = (me8200_di_subdevice_t *) dev_id;
-
- if (irq != instance->irq) {
- PERROR("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- PDEBUG("executed.\n");
-
- //Reset latches. Copy status to extended registers.
- irq_status = inb(instance->irq_status_reg);
- PDEBUG_REG("idx=%d irq_status_reg=0x%02X\n", instance->di_idx,
- irq_status);
-
- if (!irq_status) {
- PINFO
- ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
- jiffies, __func__, instance->di_idx, irq_status);
- return IRQ_NONE;
- }
-
- irq_status_EX = inb(instance->irq_status_low_reg);
- irq_status_EX |= (inb(instance->irq_status_high_reg) << 8);
-
- PDEVELOP("EXTENDED REG: 0x%04x\n", irq_status_EX);
- instance->line_value = inb(instance->port_reg);
-
- // Format extended information.
- for (i = 0, j = 0; i < 8; i++, j += 2) {
- status_val |= ((0x01 << j) & irq_status_EX) >> (j - i); //Fall
- status_val |= ((0x01 << (j + 1)) & irq_status_EX) << (15 - j + i); //Raise
- }
-
- spin_lock(&instance->subdevice_lock);
- if (instance->rised == 0) {
- instance->status_value = irq_status;
- instance->status_value_edges = status_val;
- } else {
- instance->status_value |= irq_status;
- instance->status_value_edges |= status_val;
- }
-
- if (instance->filtering_flag) { // For compare mode only.
- if (instance->compare_value == instance->line_value) {
- instance->rised = 1;
- instance->count++;
- }
- } else {
- instance->rised = 1;
- instance->count++;
- }
- spin_unlock(&instance->subdevice_lock);
-
- wake_up_interruptible_all(&instance->wait_queue);
-
- return IRQ_HANDLED;
-}
-
-static void me8200_di_destructor(struct me_subdevice *subdevice)
-{
- me8200_di_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_di_subdevice_t *) subdevice;
-
- free_irq(instance->irq, (void *)instance);
- me_subdevice_deinit(&instance->base);
- kfree(instance);
-}
-
-me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_regbase,
- unsigned int di_idx,
- int irq,
- spinlock_t *irq_ctrl_lock,
- spinlock_t *irq_mode_lock)
-{
- me8200_di_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me8200_di_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me8200_di_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Check firmware version.
- me8200_di_check_version(subdevice,
- me8200_regbase + ME8200_FIRMWARE_VERSION_REG);
-
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->irq_ctrl_lock = irq_ctrl_lock;
- subdevice->irq_mode_lock = irq_mode_lock;
-
- /* Save the subdevice index. */
- subdevice->di_idx = di_idx;
-
- /* Initialize registers */
- if (di_idx == 0) {
- subdevice->port_reg = me8200_regbase + ME8200_DI_PORT_0_REG;
- subdevice->mask_reg = me8200_regbase + ME8200_DI_MASK_0_REG;
- subdevice->compare_reg =
- me8200_regbase + ME8200_DI_COMPARE_0_REG;
- subdevice->irq_status_reg =
- me8200_regbase + ME8200_DI_CHANGE_0_REG;
-
- subdevice->irq_status_low_reg =
- me8200_regbase + ME8200_DI_EXTEND_CHANGE_0_LOW_REG;
- subdevice->irq_status_high_reg =
- me8200_regbase + ME8200_DI_EXTEND_CHANGE_0_HIGH_REG;
- } else if (di_idx == 1) {
- subdevice->port_reg = me8200_regbase + ME8200_DI_PORT_1_REG;
- subdevice->mask_reg = me8200_regbase + ME8200_DI_MASK_1_REG;
- subdevice->compare_reg =
- me8200_regbase + ME8200_DI_COMPARE_1_REG;
- subdevice->irq_status_reg =
- me8200_regbase + ME8200_DI_CHANGE_1_REG;
-
- subdevice->irq_status_low_reg =
- me8200_regbase + ME8200_DI_EXTEND_CHANGE_1_LOW_REG;
- subdevice->irq_status_high_reg =
- me8200_regbase + ME8200_DI_EXTEND_CHANGE_1_HIGH_REG;
- } else {
- PERROR("Wrong subdevice idx=%d.\n", di_idx);
- kfree(subdevice);
- return NULL;
- }
- subdevice->irq_ctrl_reg = me8200_regbase + ME8200_DI_IRQ_CTRL_REG;
- subdevice->irq_mode_reg = me8200_regbase + ME8200_IRQ_MODE_REG;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = me8200_regbase;
-#endif
-
- /* Initialize wait queue */
- init_waitqueue_head(&subdevice->wait_queue);
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_irq_start = me8200_di_io_irq_start;
- subdevice->base.me_subdevice_io_irq_wait = me8200_di_io_irq_wait;
- subdevice->base.me_subdevice_io_irq_stop = me8200_di_io_irq_stop;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me8200_di_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me8200_di_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me8200_di_io_single_read;
- subdevice->base.me_subdevice_query_number_channels =
- me8200_di_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me8200_di_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me8200_di_query_subdevice_caps;
- subdevice->base.me_subdevice_destructor = me8200_di_destructor;
-
- subdevice->rised = 0;
- subdevice->count = 0;
-
- /* Register interrupt service routine. */
- subdevice->irq = irq;
- if (subdevice->version > 0) { // NEW
- err = request_irq(subdevice->irq, me8200_isr_EX,
- IRQF_DISABLED | IRQF_SHARED,
- ME8200_NAME, (void *)subdevice);
- } else { //OLD
- err = request_irq(subdevice->irq, me8200_isr,
- IRQF_DISABLED | IRQF_SHARED,
- ME8200_NAME, (void *)subdevice);
- }
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- PDEBUG("Registred irq=%d.\n", subdevice->irq);
-
- return subdevice;
-}
-
-static void me8200_di_check_version(me8200_di_subdevice_t *instance,
- unsigned long addr)
-{
-
- PDEBUG("executed.\n");
- instance->version = 0x000000FF & inb(addr);
- PDEVELOP("me8200 firmware version: %d\n", instance->version);
-
- /// @note Fix for wrong values in this registry.
- if ((instance->version < 0x7) || (instance->version > 0x1F))
- instance->version = 0x0;
-}
diff --git a/drivers/staging/meilhaus/me8200_di.h b/drivers/staging/meilhaus/me8200_di.h
deleted file mode 100644
index 2a3b005..0000000
--- a/drivers/staging/meilhaus/me8200_di.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * @file me8200_di.h
- *
- * @brief ME-8200 digital input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8200_DI_H_
-#define _ME8200_DI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me8200_di_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock;
- spinlock_t *irq_ctrl_lock;
- spinlock_t *irq_mode_lock;
-
- unsigned int di_idx;
- unsigned int version;
-
- int irq; /**< The number of the interrupt request. */
- volatile int rised; /**< Flag to indicate if an interrupt occured. */
- uint status_flag; /**< Default interupt status flag */
- uint status_value; /**< Interupt status */
- uint status_value_edges; /**< Extended interupt status */
- uint line_value;
- int count; /**< Counts the number of interrupts occured. */
- uint8_t compare_value;
- uint8_t filtering_flag;
-
- wait_queue_head_t wait_queue; /**< To wait on interrupts. */
-
- unsigned long port_reg; /**< The digital input port. */
- unsigned long compare_reg; /**< The register to hold the value to compare with. */
- unsigned long mask_reg; /**< The register to hold the mask. */
- unsigned long irq_mode_reg; /**< The interrupt mode register. */
- unsigned long irq_ctrl_reg; /**< The interrupt control register. */
- unsigned long irq_status_reg; /**< The interrupt status register. Also interrupt reseting register (firmware version 7 and later).*/
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
- unsigned long firmware_version_reg; /**< The interrupt reseting register. */
-
- unsigned long irq_status_low_reg; /**< The interrupt extended status register (low part). */
- unsigned long irq_status_high_reg; /**< The interrupt extended status register (high part). */
-} me8200_di_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-8200 digital input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_reg_base,
- unsigned int di_idx,
- int irq,
- spinlock_t * irq_ctrl_lock,
- spinlock_t * irq_mode_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_di_reg.h b/drivers/staging/meilhaus/me8200_di_reg.h
deleted file mode 100644
index b9a619d..0000000
--- a/drivers/staging/meilhaus/me8200_di_reg.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * @file me8200_di_reg.h
- *
- * @brief ME-8200 digital input subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8200_DI_REG_H_
-#define _ME8200_DI_REG_H_
-
-#ifdef __KERNEL__
-
-// Common registry for whole family.
-#define ME8200_DI_PORT_0_REG 0x3 // R
-#define ME8200_DI_PORT_1_REG 0x4 // R
-
-#define ME8200_DI_MASK_0_REG 0x5 // R/W
-#define ME8200_DI_MASK_1_REG 0x6 // R/W
-
-#define ME8200_DI_COMPARE_0_REG 0xA // R/W
-#define ME8200_DI_COMPARE_1_REG 0xB // R/W
-
-#define ME8200_DI_IRQ_CTRL_REG 0xC // R/W
-
-#ifndef ME8200_IRQ_MODE_REG
-# define ME8200_IRQ_MODE_REG 0xD // R/W
-#endif
-
-// This registry are for all versions
-#define ME8200_DI_CHANGE_0_REG 0xE // R
-#define ME8200_DI_CHANGE_1_REG 0xF // R
-
-#define ME8200_DI_IRQ_CTRL_BIT_CLEAR 0x4
-#define ME8200_DI_IRQ_CTRL_BIT_ENABLE 0x8
-
-// This registry are for firmware versions 7 and later
-#define ME8200_DI_EXTEND_CHANGE_0_LOW_REG 0x10 // R
-#define ME8200_DI_EXTEND_CHANGE_0_HIGH_REG 0x11 // R
-#define ME8200_DI_EXTEND_CHANGE_1_LOW_REG 0x12 // R
-#define ME8200_DI_EXTEND_CHANGE_1_HIGH_REG 0x13 // R
-
-#ifndef ME8200_FIRMWARE_VERSION_REG
-# define ME8200_FIRMWARE_VERSION_REG 0x14 // R
-#endif
-
-// Bit definitions
-#define ME8200_DI_IRQ_CTRL_MASK_EDGE 0x3
-#define ME8200_DI_IRQ_CTRL_MASK_EDGE_RISING 0x0
-#define ME8200_DI_IRQ_CTRL_MASK_EDGE_FALLING 0x1
-#define ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY 0x3
-
-// Others
-#define ME8200_DI_IRQ_CTRL_SHIFT 4
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_dio.c b/drivers/staging/meilhaus/me8200_dio.c
deleted file mode 100644
index c7f43f0..0000000
--- a/drivers/staging/meilhaus/me8200_dio.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/**
- * @file me8200_dio.c
- *
- * @brief ME-8200 digital input/output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me8200_dio_reg.h"
-#include "me8200_dio.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me8200_dio_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me8200_dio_subdevice_t *instance;
- uint8_t mode;
-
- PDEBUG("executed.\n");
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- instance = (me8200_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inb(instance->ctrl_reg);
- mode &= ~(0x3 << (instance->dio_idx * 2));
- outb(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- spin_unlock(instance->ctrl_reg_lock);
- outb(0x00, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->port_reg - instance->reg_base, 0x00);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_dio_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me8200_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint32_t mode;
- uint32_t size =
- flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
- | ME_IO_SINGLE_CONFIG_DIO_WORD |
- ME_IO_SINGLE_CONFIG_DIO_DWORD);
-
- PDEBUG("executed.\n");
-
- instance = (me8200_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- mode = inb(instance->ctrl_reg);
- switch (size) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_BYTE:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
- mode &=
- ~((ME8200_DIO_CTRL_BIT_MODE_0 |
- ME8200_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
- mode &=
- ~((ME8200_DIO_CTRL_BIT_MODE_0 |
- ME8200_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
- mode |=
- ME8200_DIO_CTRL_BIT_MODE_0 << (instance->
- dio_idx * 2);
- } else {
- PERROR
- ("Invalid port configuration specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid channel number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
-
- break;
-
- default:
- PERROR("Invalid flags.\n");
-
- err = ME_ERRNO_INVALID_FLAGS;
- }
-
- if (!err) {
- outb(mode, instance->ctrl_reg);
- PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->ctrl_reg - instance->reg_base, mode);
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_dio_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me8200_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t mode;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
- ME8200_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
-
- if ((mode ==
- (ME8200_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) || !mode) {
- *value =
- inb(instance->
- port_reg) & (0x0001 << channel);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
- ME8200_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
-
- if ((mode ==
- (ME8200_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) || !mode) {
- *value = inb(instance->port_reg) & 0x00FF;
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_dio_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me8200_dio_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t mode;
- uint8_t byte;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_dio_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
- ME8200_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
-
- if (mode ==
- (ME8200_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) {
- byte = inb(instance->port_reg);
-
- if (value)
- byte |= 0x1 << channel;
- else
- byte &= ~(0x1 << channel);
-
- outb(byte, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg -
- instance->reg_base, byte);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- mode =
- inb(instance->
- ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
- ME8200_DIO_CTRL_BIT_MODE_1) <<
- (instance->dio_idx * 2));
-
- if (mode ==
- (ME8200_DIO_CTRL_BIT_MODE_0 <<
- (instance->dio_idx * 2))) {
- outb(value, instance->port_reg);
- PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg -
- instance->reg_base, value);
- } else {
- PERROR("Port not in output or input mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(instance->ctrl_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_dio_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_dio_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DIO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_dio_query_subdevice_caps(me_subdevice_t *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_DIO_DIR_BYTE;
- return ME_ERRNO_SUCCESS;
-}
-
-me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base,
- unsigned int dio_idx,
- spinlock_t *ctrl_reg_lock)
-{
- me8200_dio_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me8200_dio_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me8200_dio_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Save digital i/o index */
- subdevice->dio_idx = dio_idx;
-
- /* Save the subdevice index */
- subdevice->ctrl_reg = reg_base + ME8200_DIO_CTRL_REG;
- subdevice->port_reg = reg_base + ME8200_DIO_PORT_REG + dio_idx;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me8200_dio_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me8200_dio_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me8200_dio_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me8200_dio_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me8200_dio_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me8200_dio_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me8200_dio_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8200_dio.h b/drivers/staging/meilhaus/me8200_dio.h
deleted file mode 100644
index 9ddd93d..0000000
--- a/drivers/staging/meilhaus/me8200_dio.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file me8200_dio.h
- *
- * @brief ME-8200 digital input/output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8200_DIO_H_
-#define _ME8200_DIO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me8200_dio_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */
- unsigned int dio_idx; /**< The index of the digital i/o on the device. */
-
- unsigned long port_reg; /**< Register holding the port status. */
- unsigned long ctrl_reg; /**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me8200_dio_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-8200 digital input/ouput subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param dio_idx The index of the digital i/o port on the device.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base,
- unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_dio_reg.h b/drivers/staging/meilhaus/me8200_dio_reg.h
deleted file mode 100644
index ac94a13..0000000
--- a/drivers/staging/meilhaus/me8200_dio_reg.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file me8200_dio_reg.h
- *
- * @brief ME-8200 digital input/output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8200_DIO_REG_H_
-#define _ME8200_DIO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8200_DIO_CTRL_REG 0x7 // R/W
-#define ME8200_DIO_PORT_0_REG 0x8 // R/W
-#define ME8200_DIO_PORT_1_REG 0x9 // R/W
-#define ME8200_DIO_PORT_REG ME8200_DIO_PORT_0_REG // R/W
-
-#define ME8200_DIO_CTRL_BIT_MODE_0 0x01
-#define ME8200_DIO_CTRL_BIT_MODE_1 0x02
-#define ME8200_DIO_CTRL_BIT_MODE_2 0x04
-#define ME8200_DIO_CTRL_BIT_MODE_3 0x08
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_do.c b/drivers/staging/meilhaus/me8200_do.c
deleted file mode 100644
index e42a137..0000000
--- a/drivers/staging/meilhaus/me8200_do.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/**
- * @file me8200_do.c
- *
- * @brief ME-8200 digital output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "meids.h"
-#include "medebug.h"
-#include "me8200_reg.h"
-#include "me8200_do_reg.h"
-#include "me8200_do.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me8200_do_io_irq_start(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int irq_source,
- int irq_edge, int irq_arg, int flags)
-{
- me8200_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t tmp;
- unsigned long status;
-
- if (flags & ~ME_IO_IRQ_START_DIO_BYTE) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel != 0) {
- PERROR("Invalid channel specified.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- if (irq_source != ME_IRQ_SOURCE_DIO_OVER_TEMP) {
- PERROR("Invalid interrupt source specified.\n");
- return ME_ERRNO_INVALID_IRQ_SOURCE;
- }
-
- PDEBUG("executed.\n");
-
- instance = (me8200_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, status);
- spin_lock(instance->irq_mode_lock);
- tmp = inb(instance->irq_ctrl_reg);
- tmp |=
- ME8200_IRQ_MODE_BIT_ENABLE_POWER << (ME8200_IRQ_MODE_POWER_SHIFT *
- instance->do_idx);
- outb(tmp, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, tmp);
- spin_unlock(instance->irq_mode_lock);
- instance->rised = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_do_io_irq_wait(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *irq_count,
- int *value, int time_out, int flags)
-{
- me8200_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- long t = 0;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_do_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (time_out < 0) {
- PERROR("Invalid time_out specified.\n");
- return ME_ERRNO_INVALID_TIMEOUT;
- }
-
- if (time_out) {
- t = (time_out * HZ) / 1000;
-
- if (t == 0)
- t = 1;
- }
-
- ME_SUBDEVICE_ENTER;
-
- if (instance->rised <= 0) {
- instance->rised = 0;
-
- if (time_out) {
- t = wait_event_interruptible_timeout(instance->
- wait_queue,
- (instance->rised !=
- 0), t);
-
- if (t == 0) {
- PERROR
- ("Wait on external interrupt timed out.\n");
- err = ME_ERRNO_TIMEOUT;
- }
- } else {
- wait_event_interruptible(instance->wait_queue,
- (instance->rised != 0));
- }
-
- if (instance->rised < 0) {
- PERROR("Wait on interrupt aborted by user.\n");
- err = ME_ERRNO_CANCELLED;
- }
- }
-
- if (signal_pending(current)) {
- PERROR("Wait on external interrupt aborted by signal.\n");
- err = ME_ERRNO_SIGNAL;
- }
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- instance->rised = 0;
- *irq_count = instance->count;
- *value = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_do_io_irq_stop(me_subdevice_t *subdevice,
- struct file *filep, int channel, int flags)
-{
- me8200_do_subdevice_t *instance;
- uint8_t tmp;
- unsigned long cpu_flags;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_do_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- spin_lock(instance->irq_mode_lock);
- tmp = inb(instance->irq_ctrl_reg);
- tmp &=
- ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER <<
- (ME8200_IRQ_MODE_POWER_SHIFT * instance->do_idx));
- outb(tmp, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, tmp);
- spin_unlock(instance->irq_mode_lock);
- instance->rised = -1;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_do_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me8200_do_subdevice_t *instance;
- unsigned long cpu_flags;
- uint8_t tmp;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_do_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
- outb(0x00, instance->port_reg);
- PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->port_reg - instance->reg_base, 0x00);
- spin_lock(instance->irq_mode_lock);
- tmp = inb(instance->irq_ctrl_reg);
- tmp &=
- ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER <<
- (ME8200_IRQ_MODE_POWER_SHIFT * instance->do_idx));
- outb(tmp, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, tmp);
- spin_unlock(instance->irq_mode_lock);
- instance->rised = -1;
- instance->count = 0;
- spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- wake_up_interruptible_all(&instance->wait_queue);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_do_io_single_config(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me8200_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long status;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, status);
- switch (flags) {
- case ME_IO_SINGLE_CONFIG_NO_FLAGS:
- case ME_IO_SINGLE_CONFIG_DIO_BYTE:
- if (channel == 0) {
- if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
- } else {
- PERROR("Invalid byte direction specified.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- PERROR("Invalid byte specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_do_io_single_read(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me8200_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- unsigned long status;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, status);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- *value = inb(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = inb(instance->port_reg);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_do_io_single_write(me_subdevice_t *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me8200_do_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
- uint8_t state;
- unsigned long status;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_do_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock_irqsave(&instance->subdevice_lock, status);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- state = inb(instance->port_reg);
- state =
- value ? (state | (0x1 << channel)) : (state &
- ~(0x1 <<
- channel));
- outb(state, instance->port_reg);
- PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg - instance->reg_base,
- state);
- } else {
- PERROR("Invalid bit number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- outb(value, instance->port_reg);
- PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n",
- instance->reg_base,
- instance->port_reg - instance->reg_base,
- value);
- } else {
- PERROR("Invalid byte number specified.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8200_do_query_number_channels(me_subdevice_t *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = 8;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_do_query_subdevice_type(me_subdevice_t *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_DIO_OVER_TEMP_IRQ;
- return ME_ERRNO_SUCCESS;
-}
-
-static void me8200_do_destructor(struct me_subdevice *subdevice)
-{
- me8200_do_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me8200_do_subdevice_t *) subdevice;
-
- free_irq(instance->irq, (void *)instance);
- me_subdevice_deinit(&instance->base);
- kfree(instance);
-}
-
-static irqreturn_t me8200_do_isr(int irq, void *dev_id)
-{
- me8200_do_subdevice_t *instance;
- uint16_t ctrl;
- uint8_t irq_status;
-
- instance = (me8200_do_subdevice_t *) dev_id;
-
- if (irq != instance->irq) {
- PERROR("Incorrect interrupt num: %d.\n", irq);
- return IRQ_NONE;
- }
-
- irq_status = inb(instance->irq_status_reg);
- if (!
- (irq_status &
- (ME8200_DO_IRQ_STATUS_BIT_ACTIVE << instance->do_idx))) {
- PINFO
- ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
- jiffies, __func__, instance->do_idx, irq_status);
- return IRQ_NONE;
- }
-
- PDEBUG("executed.\n");
-
- spin_lock(&instance->subdevice_lock);
- instance->rised = 1;
- instance->count++;
-
- spin_lock(instance->irq_mode_lock);
- ctrl = inw(instance->irq_ctrl_reg);
- ctrl |= ME8200_IRQ_MODE_BIT_CLEAR_POWER << instance->do_idx;
- outw(ctrl, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, ctrl);
- ctrl &= ~(ME8200_IRQ_MODE_BIT_CLEAR_POWER << instance->do_idx);
- outw(ctrl, instance->irq_ctrl_reg);
- PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
- instance->irq_ctrl_reg - instance->reg_base, ctrl);
- spin_unlock(instance->irq_mode_lock);
- spin_unlock(&instance->subdevice_lock);
- wake_up_interruptible_all(&instance->wait_queue);
-
- return IRQ_HANDLED;
-}
-
-me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base,
- unsigned int do_idx,
- int irq,
- spinlock_t *irq_mode_lock)
-{
- me8200_do_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me8200_do_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for subdevice instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me8200_do_subdevice_t));
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->irq_mode_lock = irq_mode_lock;
-
- /* Save the index of the digital output */
- subdevice->do_idx = do_idx;
- subdevice->irq = irq;
-
- /* Initialize the registers */
- if (do_idx == 0) {
- subdevice->port_reg = reg_base + ME8200_DO_PORT_0_REG;
- } else if (do_idx == 1) {
- subdevice->port_reg = reg_base + ME8200_DO_PORT_1_REG;
- } else {
- PERROR("Wrong subdevice idx=%d.\n", do_idx);
- kfree(subdevice);
- return NULL;
- }
- subdevice->irq_ctrl_reg = reg_base + ME8200_IRQ_MODE_REG;
- subdevice->irq_status_reg = reg_base + ME8200_DO_IRQ_STATUS_REG;
-#ifdef MEDEBUG_DEBUG_REG
- subdevice->reg_base = reg_base;
-#endif
-
- /* Initialize the wait queue */
- init_waitqueue_head(&subdevice->wait_queue);
-
- /* Request the interrupt line */
- err = request_irq(irq, me8200_do_isr,
- IRQF_DISABLED | IRQF_SHARED,
- ME8200_NAME, (void *)subdevice);
-
- if (err) {
- PERROR("Cannot get interrupt line.\n");
- kfree(subdevice);
- return NULL;
- }
- PINFO("Registered irq=%d.\n", irq);
-
- /* Overload base class methods. */
- subdevice->base.me_subdevice_io_irq_start = me8200_do_io_irq_start;
- subdevice->base.me_subdevice_io_irq_wait = me8200_do_io_irq_wait;
- subdevice->base.me_subdevice_io_irq_stop = me8200_do_io_irq_stop;
- subdevice->base.me_subdevice_io_reset_subdevice =
- me8200_do_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config =
- me8200_do_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me8200_do_io_single_read;
- subdevice->base.me_subdevice_io_single_write =
- me8200_do_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me8200_do_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me8200_do_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me8200_do_query_subdevice_caps;
- subdevice->base.me_subdevice_destructor = me8200_do_destructor;
-
- subdevice->rised = 0;
- subdevice->count = 0;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8200_do.h b/drivers/staging/meilhaus/me8200_do.h
deleted file mode 100644
index 2758125..0000000
--- a/drivers/staging/meilhaus/me8200_do.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * @file me8200_do.h
- *
- * @brief ME-8200 digital output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8200_DO_H_
-#define _ME8200_DO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me8200_do_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
- spinlock_t *irq_mode_lock;
-
- int irq; /**< The number of the interrupt request */
- int rised; /**< Flag to indicate if an interrupt occured */
- int count; /**< Counts the number of interrupts occured */
- wait_queue_head_t wait_queue; /**< To wait on interrupts */
-
- unsigned int do_idx; /**< The number of the digital output */
-
- unsigned long port_reg; /**< The digital output port */
- unsigned long irq_ctrl_reg; /**< The interrupt control register */
- unsigned long irq_status_reg; /**< The interrupt status register */
-#ifdef MEDEBUG_DEBUG_REG
- unsigned long reg_base;
-#endif
-} me8200_do_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-8200 digital output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param do_idx The index of the digital output subdevice on this device.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base,
- unsigned int do_idx,
- int irq,
- spinlock_t * irq_mode_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_do_reg.h b/drivers/staging/meilhaus/me8200_do_reg.h
deleted file mode 100644
index 4109504..0000000
--- a/drivers/staging/meilhaus/me8200_do_reg.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @file me8200_ao_reg.h
- *
- * @brief ME-8200 analog output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8200_DO_REG_H_
-#define _ME8200_DO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8200_DO_IRQ_STATUS_REG 0x0 // R
-#define ME8200_DO_PORT_0_REG 0x1 // R/W
-#define ME8200_DO_PORT_1_REG 0x2 // R/W
-
-#define ME8200_DO_IRQ_STATUS_BIT_ACTIVE 0x1
-#define ME8200_DO_IRQ_STATUS_SHIFT 1
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_reg.h b/drivers/staging/meilhaus/me8200_reg.h
deleted file mode 100644
index a73fe4d..0000000
--- a/drivers/staging/meilhaus/me8200_reg.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file me8200_reg.h
- *
- * @brief ME-8200 register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8200_REG_H_
-#define _ME8200_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8200_IRQ_MODE_REG 0xD // R/W
-
-#define ME8200_IRQ_MODE_MASK 0x3
-
-#define ME8200_IRQ_MODE_MASK_MASK 0x0
-#define ME8200_IRQ_MODE_MASK_COMPARE 0x1
-
-#define ME8200_IRQ_MODE_BIT_ENABLE_POWER 0x10
-#define ME8200_IRQ_MODE_BIT_CLEAR_POWER 0x40
-
-#define ME8200_IRQ_MODE_DI_SHIFT 2
-#define ME8200_IRQ_MODE_POWER_SHIFT 1
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8254.c b/drivers/staging/meilhaus/me8254.c
deleted file mode 100644
index d8f742a..0000000
--- a/drivers/staging/meilhaus/me8254.c
+++ /dev/null
@@ -1,1176 +0,0 @@
-/**
- * @file me8254.c
- *
- * @brief 8254 subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me8254_reg.h"
-#include "me8254.h"
-
-/*
- * Defines
- */
-#define ME8254_NUMBER_CHANNELS 1 /**< One channel per counter. */
-#define ME8254_CTR_WIDTH 16 /**< One counter has 16 bits. */
-
-/*
- * Functions
- */
-
-static int me8254_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me8254_subdevice_t *instance;
- uint8_t clk_src;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me8254_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- if (instance->ctr_idx == 0)
- outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- else if (instance->ctr_idx == 1)
- outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- else
- outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- spin_unlock(instance->ctrl_reg_lock);
-
- outb(0x00, instance->val_reg);
- outb(0x00, instance->val_reg);
-
- spin_lock(instance->clk_src_reg_lock);
- clk_src = inb(instance->clk_src_reg);
-
- switch (instance->device_id) {
- case PCI_DEVICE_ID_MEILHAUS_ME1400:
- case PCI_DEVICE_ID_MEILHAUS_ME140A:
- case PCI_DEVICE_ID_MEILHAUS_ME140B:
- case PCI_DEVICE_ID_MEILHAUS_ME14E0:
- case PCI_DEVICE_ID_MEILHAUS_ME14EA:
- case PCI_DEVICE_ID_MEILHAUS_ME14EB:
- if (instance->me8254_idx == 0) {
- if (instance->ctr_idx == 0)
- clk_src &=
- ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ |
- ME1400AB_8254_A_0_CLK_SRC_QUARZ);
- else if (instance->ctr_idx == 1)
- clk_src &= ~(ME1400AB_8254_A_1_CLK_SRC_PREV);
- else
- clk_src &= ~(ME1400AB_8254_A_2_CLK_SRC_PREV);
- } else {
- if (instance->ctr_idx == 0)
- clk_src &=
- ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ |
- ME1400AB_8254_B_0_CLK_SRC_QUARZ);
- else if (instance->ctr_idx == 1)
- clk_src &= ~(ME1400AB_8254_B_1_CLK_SRC_PREV);
- else
- clk_src &= ~(ME1400AB_8254_B_2_CLK_SRC_PREV);
- }
- break;
-
- case PCI_DEVICE_ID_MEILHAUS_ME140C:
- case PCI_DEVICE_ID_MEILHAUS_ME140D:
- switch (instance->me8254_idx) {
- case 0:
- case 2:
- case 4:
- case 6:
- case 8:
- if (instance->ctr_idx == 0)
- clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
- else if (instance->ctr_idx == 1)
- clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK);
- else
- clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK);
- break;
-
- default:
- if (instance->ctr_idx == 0)
- clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
- else if (instance->ctr_idx == 1)
- clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK);
- else
- clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK);
- break;
- }
- break;
-
- case PCI_DEVICE_ID_MEILHAUS_ME4610:
- case PCI_DEVICE_ID_MEILHAUS_ME4660:
- case PCI_DEVICE_ID_MEILHAUS_ME4660I:
- case PCI_DEVICE_ID_MEILHAUS_ME4660S:
- case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
- case PCI_DEVICE_ID_MEILHAUS_ME4670:
- case PCI_DEVICE_ID_MEILHAUS_ME4670I:
- case PCI_DEVICE_ID_MEILHAUS_ME4670S:
- case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
- case PCI_DEVICE_ID_MEILHAUS_ME4680:
- case PCI_DEVICE_ID_MEILHAUS_ME4680I:
- case PCI_DEVICE_ID_MEILHAUS_ME4680S:
- case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
- case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
- case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
-
- /* No clock source register available */
- break;
-
- default:
- PERROR("Invalid device type.\n");
- err = ME_ERRNO_INTERNAL;
- }
-
- if (!err)
- outb(clk_src, instance->clk_src_reg);
-
- spin_unlock(instance->clk_src_reg_lock);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me1400_ab_ref_config(me8254_subdevice_t *instance, int ref)
-{
- uint8_t clk_src;
-
- spin_lock(instance->clk_src_reg_lock);
- clk_src = inb(instance->clk_src_reg);
-
- switch (ref) {
- case ME_REF_CTR_EXTERNAL:
- if (instance->me8254_idx == 0) {
- if (instance->ctr_idx == 0)
- clk_src &= ~(ME1400AB_8254_A_0_CLK_SRC_QUARZ);
- else if (instance->ctr_idx == 1)
- clk_src &= ~(ME1400AB_8254_A_1_CLK_SRC_PREV);
- else
- clk_src &= ~(ME1400AB_8254_A_2_CLK_SRC_PREV);
- } else {
- if (instance->ctr_idx == 0)
- clk_src &= ~(ME1400AB_8254_B_0_CLK_SRC_QUARZ);
- else if (instance->ctr_idx == 1)
- clk_src &= ~(ME1400AB_8254_B_1_CLK_SRC_PREV);
- else
- clk_src &= ~(ME1400AB_8254_B_2_CLK_SRC_PREV);
- }
-
- break;
-
- case ME_REF_CTR_PREVIOUS:
- if (instance->me8254_idx == 0) {
- if (instance->ctr_idx == 0) {
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- } else if (instance->ctr_idx == 1)
- clk_src |= (ME1400AB_8254_A_1_CLK_SRC_PREV);
- else
- clk_src |= (ME1400AB_8254_A_2_CLK_SRC_PREV);
- } else {
- if (instance->ctr_idx == 0) {
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- } else if (instance->ctr_idx == 1)
- clk_src |= (ME1400AB_8254_B_1_CLK_SRC_PREV);
- else
- clk_src |= (ME1400AB_8254_B_2_CLK_SRC_PREV);
- }
-
- break;
-
- case ME_REF_CTR_INTERNAL_1MHZ:
- if (instance->me8254_idx == 0) {
- if (instance->ctr_idx == 0) {
- clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ);
- clk_src &= ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ);
- } else {
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- if (instance->ctr_idx == 0) {
- clk_src |= (ME1400AB_8254_B_0_CLK_SRC_QUARZ);
- clk_src &= ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ);
- } else {
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- }
-
- break;
-
- case ME_REF_CTR_INTERNAL_10MHZ:
- if (instance->me8254_idx == 0) {
- if (instance->ctr_idx == 0) {
- clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ);
- clk_src |= (ME1400AB_8254_A_0_CLK_SRC_10MHZ);
- } else {
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- if (instance->ctr_idx == 0) {
- clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ);
- clk_src |= (ME1400AB_8254_A_0_CLK_SRC_10MHZ);
- } else {
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- }
-
- break;
-
- default:
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_REF;
- }
-
- outb(clk_src, instance->clk_src_reg);
- spin_unlock(instance->clk_src_reg_lock);
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me1400_cd_ref_config(me8254_subdevice_t *instance, int ref)
-{
- uint8_t clk_src;
-
- spin_lock(instance->clk_src_reg_lock);
- clk_src = inb(instance->clk_src_reg);
-
- switch (ref) {
- case ME_REF_CTR_EXTERNAL:
- switch (instance->me8254_idx) {
- case 0:
- case 2:
- case 4:
- case 6:
- case 8:
- if (instance->ctr_idx == 0)
- clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
- else if (instance->ctr_idx == 1)
- clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK);
- else
- clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK);
- break;
-
- default:
- if (instance->ctr_idx == 0)
- clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
- else if (instance->ctr_idx == 1)
- clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK);
- else
- clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK);
- break;
- }
- break;
-
- case ME_REF_CTR_PREVIOUS:
- switch (instance->me8254_idx) {
- case 0:
- case 2:
- case 4:
- case 6:
- case 8:
- if (instance->ctr_idx == 0) {
- clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
- clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_PREV);
- } else if (instance->ctr_idx == 1) {
- clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK);
- clk_src |= (ME1400CD_8254_ACE_1_CLK_SRC_PREV);
- } else {
- clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK);
- clk_src |= (ME1400CD_8254_ACE_2_CLK_SRC_PREV);
- }
- break;
-
- default:
- if (instance->ctr_idx == 0) {
- clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
- clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_PREV);
- } else if (instance->ctr_idx == 1) {
- clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK);
- clk_src |= (ME1400CD_8254_BD_1_CLK_SRC_PREV);
- } else {
- clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK);
- clk_src |= (ME1400CD_8254_BD_2_CLK_SRC_PREV);
- }
- break;
- }
-
- break;
-
- case ME_REF_CTR_INTERNAL_1MHZ:
- switch (instance->me8254_idx) {
- case 0:
- case 2:
- case 4:
- case 6:
- case 8:
- if (instance->ctr_idx == 0) {
- clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
- clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_1MHZ);
- } else {
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_REF;
- }
-
- break;
-
- default:
- if (instance->ctr_idx == 0) {
- clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
- clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_1MHZ);
- } else {
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_REF;
- }
- break;
- }
-
- break;
-
- case ME_REF_CTR_INTERNAL_10MHZ:
- switch (instance->me8254_idx) {
- case 0:
- case 2:
- case 4:
- case 6:
- case 8:
- if (instance->ctr_idx == 0) {
- clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
- clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_10MHZ);
- } else {
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_REF;
- }
- break;
-
- default:
- if (instance->ctr_idx == 0) {
- clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
- clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_10MHZ);
- } else {
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_REF;
- }
-
- break;
- }
-
- break;
-
- default:
- PERROR("Invalid reference.\n");
- spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_REF;
- }
-
- outb(clk_src, instance->clk_src_reg);
- spin_unlock(instance->clk_src_reg_lock);
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ref_config(me8254_subdevice_t *instance, int ref)
-{
- switch (ref) {
-
- case ME_REF_CTR_EXTERNAL:
- // Nothing to do
- break;
-
- default:
- PERROR("Invalid reference.\n");
-// spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_REF;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_ref_config(me8254_subdevice_t *instance, int ref)
-{
- switch (ref) {
-
- case ME_REF_CTR_EXTERNAL:
- // Nothing to do
- break;
-
- default:
- PERROR("Invalid reference.\n");
-// spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_REF;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_io_single_config(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me8254_subdevice_t *instance;
- int err;
-
- PDEBUG("executed.\n");
-
- if (channel) {
- PERROR("Invalid channel.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- instance = (me8254_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- // Configure the counter modes
- if (instance->ctr_idx == 0) {
- if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) {
- outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) {
- outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M1 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) {
- outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M2 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) {
- outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M3 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) {
- outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M4 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) {
- outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M5 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else {
- PERROR("Invalid single configuration.\n");
- spin_unlock(&instance->subdevice_lock);
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else if (instance->ctr_idx == 1) {
- if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) {
- outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) {
- outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M1 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) {
- outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M2 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) {
- outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M3 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) {
- outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M4 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) {
- outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M5 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else {
- PERROR("Invalid single configuration.\n");
- spin_unlock(&instance->subdevice_lock);
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- } else {
- if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) {
- outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) {
- outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M1 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) {
- outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M2 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) {
- outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M3 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) {
- outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M4 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) {
- outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M5 |
- ME8254_CTRL_BIN, instance->ctrl_reg);
- } else {
- PERROR("Invalid single configuration.\n");
- spin_unlock(&instance->subdevice_lock);
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- }
-
- switch (instance->device_id) {
- case PCI_DEVICE_ID_MEILHAUS_ME1400:
- case PCI_DEVICE_ID_MEILHAUS_ME14E0:
- case PCI_DEVICE_ID_MEILHAUS_ME140A:
- case PCI_DEVICE_ID_MEILHAUS_ME14EA:
- case PCI_DEVICE_ID_MEILHAUS_ME140B:
- case PCI_DEVICE_ID_MEILHAUS_ME14EB:
- err = me1400_ab_ref_config(instance, ref);
-
- if (err) {
- spin_unlock(&instance->subdevice_lock);
- return err;
- }
-
- break;
-
- case PCI_DEVICE_ID_MEILHAUS_ME140C:
- case PCI_DEVICE_ID_MEILHAUS_ME140D:
- err = me1400_cd_ref_config(instance, ref);
-
- if (err) {
- spin_unlock(&instance->subdevice_lock);
- return err;
- }
-
- break;
-
- case PCI_DEVICE_ID_MEILHAUS_ME4610:
- case PCI_DEVICE_ID_MEILHAUS_ME4660:
- case PCI_DEVICE_ID_MEILHAUS_ME4660I:
- case PCI_DEVICE_ID_MEILHAUS_ME4660S:
- case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
- case PCI_DEVICE_ID_MEILHAUS_ME4670:
- case PCI_DEVICE_ID_MEILHAUS_ME4670I:
- case PCI_DEVICE_ID_MEILHAUS_ME4670S:
- case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
- case PCI_DEVICE_ID_MEILHAUS_ME4680:
- case PCI_DEVICE_ID_MEILHAUS_ME4680I:
- case PCI_DEVICE_ID_MEILHAUS_ME4680S:
- case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
- err = me4600_ref_config(instance, ref);
-
- if (err) {
- spin_unlock(&instance->subdevice_lock);
- return err;
- }
-
- break;
-
- case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
- case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
- err = me8100_ref_config(instance, ref);
-
- if (err) {
- spin_unlock(&instance->subdevice_lock);
- return err;
- }
-
- break;
-
- default:
- PERROR("Invalid device type.\n");
-
- spin_unlock(&instance->subdevice_lock);
-// spin_unlock(instance->clk_src_reg_lock);
- return ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_io_single_read(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me8254_subdevice_t *instance;
- uint16_t lo_byte;
- uint16_t hi_byte;
-
- PDEBUG("executed.\n");
-
- if (channel) {
- PERROR("Invalid channel.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- instance = (me8254_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- if (instance->ctr_idx == 0)
- outb(ME8254_CTRL_SC0 | ME8254_CTRL_TLO, instance->ctrl_reg);
- else if (instance->ctr_idx == 1)
- outb(ME8254_CTRL_SC1 | ME8254_CTRL_TLO, instance->ctrl_reg);
- else
- outb(ME8254_CTRL_SC2 | ME8254_CTRL_TLO, instance->ctrl_reg);
-
- lo_byte = inb(instance->val_reg);
- hi_byte = inb(instance->val_reg);
- spin_unlock(instance->ctrl_reg_lock);
-
- *value = lo_byte | (hi_byte << 8);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_io_single_write(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me8254_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- if (channel) {
- PERROR("Invalid channel.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- instance = (me8254_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- outb(value, instance->val_reg);
- outb((value >> 8), instance->val_reg);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_query_number_channels(struct me_subdevice *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = ME8254_NUMBER_CHANNELS;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_query_subdevice_type(struct me_subdevice *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_CTR;
- *subtype = ME_SUBTYPE_CTR_8254;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_query_subdevice_caps(struct me_subdevice *subdevice,
- int *caps)
-{
- me8254_subdevice_t *instance;
- PDEBUG("executed.\n");
- instance = (me8254_subdevice_t *) subdevice;
- *caps = instance->caps;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_query_subdevice_caps_args(struct me_subdevice *subdevice,
- int cap, int *args, int count)
-{
- PDEBUG("executed.\n");
-
- if (count != 1) {
- PERROR("Invalid capability argument count.\n");
- return ME_ERRNO_INVALID_CAP_ARG_COUNT;
- }
-
- if (cap == ME_CAP_CTR_WIDTH) {
- args[0] = ME8254_CTR_WIDTH;
- } else {
- PERROR("Invalid capability.\n");
- return ME_ERRNO_INVALID_CAP;
- }
-
- return ME_ERRNO_SUCCESS;
-}
-
-static uint32_t me1400AB_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
- unsigned int ctr_idx)
-{
- switch (me8254_idx) {
-
- case 0:
- return (reg_base + ME1400AB_8254_A_0_VAL_REG + ctr_idx);
-
- default:
- return (reg_base + ME1400AB_8254_B_0_VAL_REG + ctr_idx);
- }
-
- return 0;
-}
-
-static uint32_t me1400AB_get_ctrl_reg(uint32_t reg_base,
- unsigned int me8254_idx,
- unsigned int ctr_idx)
-{
- switch (me8254_idx) {
- case 0:
- return (reg_base + ME1400AB_8254_A_CTRL_REG);
-
- default:
- return (reg_base + ME1400AB_8254_B_CTRL_REG);
- }
-
- return 0;
-}
-
-static uint32_t me1400AB_get_clk_src_reg(uint32_t reg_base,
- unsigned int me8254_idx,
- unsigned int ctr_idx)
-{
- switch (me8254_idx) {
- case 0:
- return (reg_base + ME1400AB_CLK_SRC_REG);
-
- default:
- return (reg_base + ME1400AB_CLK_SRC_REG);
- }
-
- return 0;
-}
-
-static uint32_t me1400CD_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
- unsigned int ctr_idx)
-{
- switch (me8254_idx) {
- case 0:
- return (reg_base + ME1400C_8254_A_0_VAL_REG + ctr_idx);
-
- case 1:
- return (reg_base + ME1400C_8254_B_0_VAL_REG + ctr_idx);
-
- case 2:
- return (reg_base + ME1400C_8254_C_0_VAL_REG + ctr_idx);
-
- case 3:
- return (reg_base + ME1400C_8254_D_0_VAL_REG + ctr_idx);
-
- case 4:
- return (reg_base + ME1400C_8254_E_0_VAL_REG + ctr_idx);
-
- case 5:
- return (reg_base + ME1400D_8254_A_0_VAL_REG + ctr_idx);
-
- case 6:
- return (reg_base + ME1400D_8254_B_0_VAL_REG + ctr_idx);
-
- case 7:
- return (reg_base + ME1400D_8254_C_0_VAL_REG + ctr_idx);
-
- case 8:
- return (reg_base + ME1400D_8254_D_0_VAL_REG + ctr_idx);
-
- default:
- return (reg_base + ME1400D_8254_E_0_VAL_REG + ctr_idx);
- }
-
- return 0;
-}
-
-static uint32_t me1400CD_get_ctrl_reg(uint32_t reg_base,
- unsigned int me8254_idx,
- unsigned int ctr_idx)
-{
- switch (me8254_idx) {
- case 0:
- return (reg_base + ME1400C_8254_A_CTRL_REG);
-
- case 1:
- return (reg_base + ME1400C_8254_B_CTRL_REG);
-
- case 2:
- return (reg_base + ME1400C_8254_C_CTRL_REG);
-
- case 3:
- return (reg_base + ME1400C_8254_D_CTRL_REG);
-
- case 4:
- return (reg_base + ME1400C_8254_E_CTRL_REG);
-
- case 5:
- return (reg_base + ME1400D_8254_A_CTRL_REG);
-
- case 6:
- return (reg_base + ME1400D_8254_B_CTRL_REG);
-
- case 7:
- return (reg_base + ME1400D_8254_C_CTRL_REG);
-
- case 8:
- return (reg_base + ME1400D_8254_D_CTRL_REG);
-
- default:
- return (reg_base + ME1400D_8254_E_CTRL_REG);
- }
-
- return 0;
-}
-
-static uint32_t me1400CD_get_clk_src_reg(uint32_t reg_base,
- unsigned int me8254_idx,
- unsigned int ctr_idx)
-{
- switch (me8254_idx) {
- case 0:
- return (reg_base + ME1400C_CLK_SRC_0_REG);
-
- case 1:
- return (reg_base + ME1400C_CLK_SRC_0_REG);
-
- case 2:
- return (reg_base + ME1400C_CLK_SRC_1_REG);
-
- case 3:
- return (reg_base + ME1400C_CLK_SRC_1_REG);
-
- case 4:
- return (reg_base + ME1400C_CLK_SRC_2_REG);
-
- case 5:
- return (reg_base + ME1400D_CLK_SRC_0_REG);
-
- case 6:
- return (reg_base + ME1400D_CLK_SRC_0_REG);
-
- case 7:
- return (reg_base + ME1400D_CLK_SRC_1_REG);
-
- case 8:
- return (reg_base + ME1400D_CLK_SRC_1_REG);
-
- default:
- return (reg_base + ME1400D_CLK_SRC_2_REG);
- }
-
- return 0;
-}
-
-static uint32_t me4600_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
- unsigned int ctr_idx)
-{
- return (reg_base + ME4600_8254_0_VAL_REG + ctr_idx);
-}
-
-static uint32_t me4600_get_ctrl_reg(uint32_t reg_base, unsigned int me8254_idx,
- unsigned int ctr_idx)
-{
- return (reg_base + ME4600_8254_CTRL_REG);
-}
-
-static uint32_t me8100_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
- unsigned int ctr_idx)
-{
- return (reg_base + ME8100_COUNTER_REG_0 + ctr_idx * 2);
-}
-
-static uint32_t me8100_get_ctrl_reg(uint32_t reg_base, unsigned int me8254_idx,
- unsigned int ctr_idx)
-{
- return (reg_base + ME8100_COUNTER_CTRL_REG);
-}
-
-me8254_subdevice_t *me8254_constructor(uint32_t device_id,
- uint32_t reg_base,
- unsigned int me8254_idx,
- unsigned int ctr_idx,
- spinlock_t *ctrl_reg_lock,
- spinlock_t *clk_src_reg_lock)
-{
- me8254_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- // Allocate memory for subdevice instance
- subdevice = kmalloc(sizeof(me8254_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for 8254 instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me8254_subdevice_t));
-
- // Check if counter index is out of range
-
- if (ctr_idx > 2) {
- PERROR("Counter index is out of range.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize subdevice base class
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
- subdevice->clk_src_reg_lock = clk_src_reg_lock;
-
- // Save type of Meilhaus device
- subdevice->device_id = device_id;
-
- // Save the indices
- subdevice->me8254_idx = me8254_idx;
- subdevice->ctr_idx = ctr_idx;
-
- // Do device specific initialization
- switch (device_id) {
-
- case PCI_DEVICE_ID_MEILHAUS_ME140A:
- case PCI_DEVICE_ID_MEILHAUS_ME14EA:
- // Check if 8254 index is out of range
- if (me8254_idx > 0) {
- PERROR("8254 index is out of range.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
-
- case PCI_DEVICE_ID_MEILHAUS_ME140B: // Fall through
- case PCI_DEVICE_ID_MEILHAUS_ME14EB:
- // Check if 8254 index is out of range
- if (me8254_idx > 1) {
- PERROR("8254 index is out of range.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
- // Initialize the counters capabilities
- if (ctr_idx == 0)
- subdevice->caps =
- ME_CAPS_CTR_CLK_INTERNAL_1MHZ |
- ME_CAPS_CTR_CLK_INTERNAL_10MHZ |
- ME_CAPS_CTR_CLK_EXTERNAL;
- else
- subdevice->caps =
- ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_EXTERNAL;
-
- // Get the counters registers
- subdevice->val_reg =
- me1400AB_get_val_reg(reg_base, me8254_idx, ctr_idx);
- subdevice->ctrl_reg =
- me1400AB_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
- subdevice->clk_src_reg =
- me1400AB_get_clk_src_reg(reg_base, me8254_idx, ctr_idx);
- break;
-
- case PCI_DEVICE_ID_MEILHAUS_ME140C:
- // Check if 8254 index is out of range
- if (me8254_idx > 4) {
- PERROR("8254 index is out of range.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
-
- case PCI_DEVICE_ID_MEILHAUS_ME140D:
- // Check if 8254 index is out of range
- if (me8254_idx > 9) {
- PERROR("8254 index is out of range.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
- // Initialize the counters capabilities
- if (ctr_idx == 0) {
- if (me8254_idx == 0)
- subdevice->caps =
- ME_CAPS_CTR_CLK_PREVIOUS |
- ME_CAPS_CTR_CLK_INTERNAL_1MHZ |
- ME_CAPS_CTR_CLK_INTERNAL_10MHZ |
- ME_CAPS_CTR_CLK_EXTERNAL;
- else
- subdevice->caps =
- ME_CAPS_CTR_CLK_INTERNAL_1MHZ |
- ME_CAPS_CTR_CLK_INTERNAL_10MHZ |
- ME_CAPS_CTR_CLK_EXTERNAL;
- } else
- subdevice->caps =
- ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_EXTERNAL;
-
- // Get the counters registers
- subdevice->val_reg =
- me1400CD_get_val_reg(reg_base, me8254_idx, ctr_idx);
- subdevice->ctrl_reg =
- me1400CD_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
- subdevice->clk_src_reg =
- me1400CD_get_clk_src_reg(reg_base, me8254_idx, ctr_idx);
- break;
-
- case PCI_DEVICE_ID_MEILHAUS_ME4610:
- case PCI_DEVICE_ID_MEILHAUS_ME4660:
- case PCI_DEVICE_ID_MEILHAUS_ME4660I:
- case PCI_DEVICE_ID_MEILHAUS_ME4660S:
- case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
- case PCI_DEVICE_ID_MEILHAUS_ME4670:
- case PCI_DEVICE_ID_MEILHAUS_ME4670I:
- case PCI_DEVICE_ID_MEILHAUS_ME4670S:
- case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
- case PCI_DEVICE_ID_MEILHAUS_ME4680:
- case PCI_DEVICE_ID_MEILHAUS_ME4680I:
- case PCI_DEVICE_ID_MEILHAUS_ME4680S:
- case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
- // Check if 8254 index is out of range
- if (me8254_idx > 0) {
- PERROR("8254 index is out of range.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
- // Initialize the counters capabilities
- subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL;
-
- // Get the counters registers
- subdevice->val_reg =
- me4600_get_val_reg(reg_base, me8254_idx, ctr_idx);
- subdevice->ctrl_reg =
- me4600_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
- subdevice->clk_src_reg = 0; // Not used
- break;
-
- case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
- case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
- // Check if 8254 index is out of range
- if (me8254_idx > 0) {
- PERROR("8254 index is out of range.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
- // Initialize the counters capabilities
- subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL;
-
- // Get the counters registers
- subdevice->val_reg =
- me8100_get_val_reg(reg_base, me8254_idx, ctr_idx);
- subdevice->ctrl_reg =
- me8100_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
- subdevice->clk_src_reg = 0; // Not used
- break;
-
- case PCI_DEVICE_ID_MEILHAUS_ME4650:
- case PCI_DEVICE_ID_MEILHAUS_ME1400:
- case PCI_DEVICE_ID_MEILHAUS_ME14E0:
- PERROR("No 8254 subdevices available for subdevice device.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
-
- default:
- PERROR("Unknown device type.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
-
- // Overload subdevice base class methods.
- subdevice->base.me_subdevice_io_reset_subdevice =
- me8254_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config = me8254_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me8254_io_single_read;
- subdevice->base.me_subdevice_io_single_write = me8254_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me8254_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me8254_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me8254_query_subdevice_caps;
- subdevice->base.me_subdevice_query_subdevice_caps_args =
- me8254_query_subdevice_caps_args;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8254.h b/drivers/staging/meilhaus/me8254.h
deleted file mode 100644
index 572b719..0000000
--- a/drivers/staging/meilhaus/me8254.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * @file me8254.h
- *
- * @brief 8254 counter implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ME8254_H_
-#define _ME8254_H_
-
-#include "mesubdevice.h"
-#include "meslock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The 8254 subdevice class.
- */
-typedef struct me8254_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
-
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect the control register from concurrent access. */
- spinlock_t *clk_src_reg_lock; /**< Spin lock to protect the clock source register from concurrent access. */
-
- uint32_t device_id; /**< The Meilhaus device type carrying the 8254 chip. */
- int me8254_idx; /**< The index of the 8254 chip on the device. */
- int ctr_idx; /**< The index of the counter on the 8254 chip. */
-
- int caps; /**< Holds the device capabilities. */
-
- unsigned long val_reg; /**< Holds the actual counter value. */
- unsigned long ctrl_reg; /**< Register to configure the 8254 modes. */
- unsigned long clk_src_reg; /**< Register to configure the counter connections. */
-} me8254_subdevice_t;
-
-/**
- * @brief The constructor to generate a 8254 instance.
- *
- * @param device_id The kind of Meilhaus device holding the 8254.
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param me8254_idx The index of the 8254 chip on the Meilhaus device.
- * @param ctr_idx The index of the counter inside a 8254 chip.
- * @param ctrl_reg_lock Pointer to spin lock protecting the 8254 control register from concurrent access.
- * @param clk_src_reg_lock Pointer to spin lock protecting the clock source register from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8254_subdevice_t *me8254_constructor(uint32_t device_id,
- uint32_t reg_base,
- unsigned int me8254_idx,
- unsigned int ctr_idx,
- spinlock_t * ctrl_reg_lock,
- spinlock_t * clk_src_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8254_reg.h b/drivers/staging/meilhaus/me8254_reg.h
deleted file mode 100644
index 7e2c36b..0000000
--- a/drivers/staging/meilhaus/me8254_reg.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * @file me8254_reg.h
- *
- * @brief 8254 counter register definitions.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME8254_REG_H_
-#define _ME8254_REG_H_
-
-#ifdef __KERNEL__
-
-/* ME1400 A/B register offsets */
-#define ME1400AB_8254_A_0_VAL_REG 0x0004 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400AB_8254_A_1_VAL_REG 0x0005 /**< Offset of 8254 A counter 1 value register. */
-#define ME1400AB_8254_A_2_VAL_REG 0x0006 /**< Offset of 8254 A counter 2 value register. */
-#define ME1400AB_8254_A_CTRL_REG 0x0007 /**< Offset of 8254 A control register. */
-
-#define ME1400AB_8254_B_0_VAL_REG 0x000C /**< Offset of 8254 B counter 0 value register. */
-#define ME1400AB_8254_B_1_VAL_REG 0x000D /**< Offset of 8254 B counter 1 value register. */
-#define ME1400AB_8254_B_2_VAL_REG 0x000E /**< Offset of 8254 B counter 2 value register. */
-#define ME1400AB_8254_B_CTRL_REG 0x000F /**< Offset of 8254 B control register. */
-
-#define ME1400AB_CLK_SRC_REG 0x0010 /**< Offset of clock source register. */
-
-/* ME1400 C register offsets */
-#define ME1400C_8254_A_0_VAL_REG 0x0004 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400C_8254_A_1_VAL_REG 0x0005 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400C_8254_A_2_VAL_REG 0x0006 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400C_8254_A_CTRL_REG 0x0007 /**< Offset of 8254 A control register. */
-
-#define ME1400C_8254_B_0_VAL_REG 0x000C /**< Offset of 8254 B counter 0 value register. */
-#define ME1400C_8254_B_1_VAL_REG 0x000D /**< Offset of 8254 B counter 0 value register. */
-#define ME1400C_8254_B_2_VAL_REG 0x000E /**< Offset of 8254 B counter 0 value register. */
-#define ME1400C_8254_B_CTRL_REG 0x000F /**< Offset of 8254 B control register. */
-
-#define ME1400C_8254_C_0_VAL_REG 0x0010 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400C_8254_C_1_VAL_REG 0x0011 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400C_8254_C_2_VAL_REG 0x0012 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400C_8254_C_CTRL_REG 0x0013 /**< Offset of 8254 C control register. */
-
-#define ME1400C_8254_D_0_VAL_REG 0x0014 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400C_8254_D_1_VAL_REG 0x0015 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400C_8254_D_2_VAL_REG 0x0016 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400C_8254_D_CTRL_REG 0x0017 /**< Offset of 8254 D control register. */
-
-#define ME1400C_8254_E_0_VAL_REG 0x0018 /**< Offset of 8254 E counter 0 value register. */
-#define ME1400C_8254_E_1_VAL_REG 0x0019 /**< Offset of 8254 E counter 0 value register. */
-#define ME1400C_8254_E_2_VAL_REG 0x001A /**< Offset of 8254 E counter 0 value register. */
-#define ME1400C_8254_E_CTRL_REG 0x001B /**< Offset of 8254 E control register. */
-
-#define ME1400C_CLK_SRC_0_REG 0x001C /**< Offset of clock source register 0. */
-#define ME1400C_CLK_SRC_1_REG 0x001D /**< Offset of clock source register 1. */
-#define ME1400C_CLK_SRC_2_REG 0x001E /**< Offset of clock source register 2. */
-
-/* ME1400 D register offsets */
-#define ME1400D_8254_A_0_VAL_REG 0x0044 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400D_8254_A_1_VAL_REG 0x0045 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400D_8254_A_2_VAL_REG 0x0046 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400D_8254_A_CTRL_REG 0x0047 /**< Offset of 8254 A control register. */
-
-#define ME1400D_8254_B_0_VAL_REG 0x004C /**< Offset of 8254 B counter 0 value register. */
-#define ME1400D_8254_B_1_VAL_REG 0x004D /**< Offset of 8254 B counter 0 value register. */
-#define ME1400D_8254_B_2_VAL_REG 0x004E /**< Offset of 8254 B counter 0 value register. */
-#define ME1400D_8254_B_CTRL_REG 0x004F /**< Offset of 8254 B control register. */
-
-#define ME1400D_8254_C_0_VAL_REG 0x0050 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400D_8254_C_1_VAL_REG 0x0051 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400D_8254_C_2_VAL_REG 0x0052 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400D_8254_C_CTRL_REG 0x0053 /**< Offset of 8254 C control register. */
-
-#define ME1400D_8254_D_0_VAL_REG 0x0054 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400D_8254_D_1_VAL_REG 0x0055 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400D_8254_D_2_VAL_REG 0x0056 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400D_8254_D_CTRL_REG 0x0057 /**< Offset of 8254 D control register. */
-
-#define ME1400D_8254_E_0_VAL_REG 0x0058 /**< Offset of 8254 E counter 0 value register. */
-#define ME1400D_8254_E_1_VAL_REG 0x0059 /**< Offset of 8254 E counter 0 value register. */
-#define ME1400D_8254_E_2_VAL_REG 0x005A /**< Offset of 8254 E counter 0 value register. */
-#define ME1400D_8254_E_CTRL_REG 0x005B /**< Offset of 8254 E control register. */
-
-#define ME1400D_CLK_SRC_0_REG 0x005C /**< Offset of clock source register 0. */
-#define ME1400D_CLK_SRC_1_REG 0x005D /**< Offset of clock source register 1. */
-#define ME1400D_CLK_SRC_2_REG 0x005E /**< Offset of clock source register 2. */
-
-/* ME4600 register offsets */
-#define ME4600_8254_0_VAL_REG 0x0000 /**< Offset of 8254 A counter 0 value register. */
-#define ME4600_8254_1_VAL_REG 0x0001 /**< Offset of 8254 A counter 0 value register. */
-#define ME4600_8254_2_VAL_REG 0x0002 /**< Offset of 8254 A counter 0 value register. */
-#define ME4600_8254_CTRL_REG 0x0003 /**< Offset of 8254 A control register. */
-
-/* Command words for 8254 control register */
-#define ME8254_CTRL_SC0 0x00 /**< Counter 0 selection. */
-#define ME8254_CTRL_SC1 0x40 /**< Counter 1 selection. */
-#define ME8254_CTRL_SC2 0x80 /**< Counter 2 selection. */
-
-#define ME8254_CTRL_TLO 0x00 /**< Counter latching operation. */
-#define ME8254_CTRL_LSB 0x10 /**< Only read LSB. */
-#define ME8254_CTRL_MSB 0x20 /**< Only read MSB. */
-#define ME8254_CTRL_LM 0x30 /**< First read LSB, then MSB. */
-
-#define ME8254_CTRL_M0 0x00 /**< Mode 0 selection. */
-#define ME8254_CTRL_M1 0x02 /**< Mode 1 selection. */
-#define ME8254_CTRL_M2 0x04 /**< Mode 2 selection. */
-#define ME8254_CTRL_M3 0x06 /**< Mode 3 selection. */
-#define ME8254_CTRL_M4 0x08 /**< Mode 4 selection. */
-#define ME8254_CTRL_M5 0x0A /**< Mode 5 selection. */
-
-#define ME8254_CTRL_BIN 0x00 /**< Binary counter. */
-#define ME8254_CTRL_BCD 0x01 /**< BCD counter. */
-
-/* ME-1400 A/B clock source register bits */
-#define ME1400AB_8254_A_0_CLK_SRC_1MHZ (0 << 7) /**< 1MHz clock. */
-#define ME1400AB_8254_A_0_CLK_SRC_10MHZ (1 << 7) /**< 10MHz clock. */
-#define ME1400AB_8254_A_0_CLK_SRC_PIN (0 << 6) /**< CLK 0 to SUB-D. */
-#define ME1400AB_8254_A_0_CLK_SRC_QUARZ (1 << 6) /**< Connect CLK 0 with quarz. */
-
-#define ME1400AB_8254_A_1_CLK_SRC_PIN (0 << 5) /**< CLK 1 to SUB-D. */
-#define ME1400AB_8254_A_1_CLK_SRC_PREV (1 << 5) /**< Connect OUT 0 with CLK 1. */
-
-#define ME1400AB_8254_A_2_CLK_SRC_PIN (0 << 4) /**< CLK 2 to SUB-D. */
-#define ME1400AB_8254_A_2_CLK_SRC_PREV (1 << 4) /**< Connect OUT 1 with CLK 2. */
-
-#define ME1400AB_8254_B_0_CLK_SRC_1MHZ (0 << 3) /**< 1MHz clock. */
-#define ME1400AB_8254_B_0_CLK_SRC_10MHZ (1 << 3) /**< 10MHz clock. */
-#define ME1400AB_8254_B_0_CLK_SRC_PIN (0 << 2) /**< CLK 0 to SUB-D. */
-#define ME1400AB_8254_B_0_CLK_SRC_QUARZ (1 << 2) /**< Connect CLK 0 with quarz. */
-
-#define ME1400AB_8254_B_1_CLK_SRC_PIN (0 << 1) /**< CLK 1 to SUB-D. */
-#define ME1400AB_8254_B_1_CLK_SRC_PREV (1 << 1) /**< Connect OUT 0 with CLK 1. */
-
-#define ME1400AB_8254_B_2_CLK_SRC_PIN (0 << 0) /**< CLK 2 to SUB-D. */
-#define ME1400AB_8254_B_2_CLK_SRC_PREV (1 << 0) /**< Connect OUT 1 with CLK 2. */
-
-/* ME-1400 C/D clock source registers bits */
-#define ME1400CD_8254_ACE_0_CLK_SRC_MASK 0x03 /**< Masks all CLK source bits. */
-#define ME1400CD_8254_ACE_0_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */
-#define ME1400CD_8254_ACE_0_CLK_SRC_1MHZ 0x01 /**< Connect CLK to 1MHz. */
-#define ME1400CD_8254_ACE_0_CLK_SRC_10MHZ 0x02 /**< Connect CLK to 10MHz. */
-#define ME1400CD_8254_ACE_0_CLK_SRC_PREV 0x03 /**< Connect CLK to previous counter output on ME-1400 D extension. */
-
-#define ME1400CD_8254_ACE_1_CLK_SRC_MASK 0x04 /**< Masks all CLK source bits. */
-#define ME1400CD_8254_ACE_1_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */
-#define ME1400CD_8254_ACE_1_CLK_SRC_PREV 0x04 /**< Connect CLK to previous counter output. */
-
-#define ME1400CD_8254_ACE_2_CLK_SRC_MASK 0x08 /**< Masks all CLK source bits. */
-#define ME1400CD_8254_ACE_2_CLK_SRC_PIN 0x00 /**< Connect to SUB-D. */
-#define ME1400CD_8254_ACE_2_CLK_SRC_PREV 0x08 /**< Connect CLK to previous counter output. */
-
-#define ME1400CD_8254_BD_0_CLK_SRC_MASK 0x30 /**< Masks all CLK source bits. */
-#define ME1400CD_8254_BD_0_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */
-#define ME1400CD_8254_BD_0_CLK_SRC_1MHZ 0x10 /**< Connect CLK to 1MHz. */
-#define ME1400CD_8254_BD_0_CLK_SRC_10MHZ 0x20 /**< Connect CLK to 10MHz. */
-#define ME1400CD_8254_BD_0_CLK_SRC_PREV 0x30 /**< Connect CLK to previous counter output. */
-
-#define ME1400CD_8254_BD_1_CLK_SRC_MASK 0x40 /**< Masks all CLK source bits. */
-#define ME1400CD_8254_BD_1_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */
-#define ME1400CD_8254_BD_1_CLK_SRC_PREV 0x40 /**< Connect CLK to previous counter output. */
-
-#define ME1400CD_8254_BD_2_CLK_SRC_MASK 0x80 /**< Masks all CLK source bits. */
-#define ME1400CD_8254_BD_2_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */
-#define ME1400CD_8254_BD_2_CLK_SRC_PREV 0x80 /**< Connect CLK to previous counter output. */
-
-/* ME-8100 counter registers */
-#define ME8100_COUNTER_REG_0 0x18 //(r,w)
-#define ME8100_COUNTER_REG_1 0x1A //(r,w)
-#define ME8100_COUNTER_REG_2 0x1C //(r,w)
-#define ME8100_COUNTER_CTRL_REG 0x1E //(r,w)
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8255.c b/drivers/staging/meilhaus/me8255.c
deleted file mode 100644
index ec9c638..0000000
--- a/drivers/staging/meilhaus/me8255.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/**
- * @file me8255.c
- *
- * @brief 8255 subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "medebug.h"
-
-#include "me8255_reg.h"
-#include "me8255.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static uint8_t get_mode_from_mirror(uint32_t mirror)
-{
- PDEBUG("executed.\n");
-
- if (mirror & ME8255_PORT_0_OUTPUT) {
- if (mirror & ME8255_PORT_1_OUTPUT) {
- if (mirror & ME8255_PORT_2_OUTPUT) {
- return ME8255_MODE_OOO;
- } else {
- return ME8255_MODE_IOO;
- }
- } else {
- if (mirror & ME8255_PORT_2_OUTPUT) {
- return ME8255_MODE_OIO;
- } else {
- return ME8255_MODE_IIO;
- }
- }
- } else {
- if (mirror & ME8255_PORT_1_OUTPUT) {
- if (mirror & ME8255_PORT_2_OUTPUT) {
- return ME8255_MODE_OOI;
- } else {
- return ME8255_MODE_IOI;
- }
- } else {
- if (mirror & ME8255_PORT_2_OUTPUT) {
- return ME8255_MODE_OII;
- } else {
- return ME8255_MODE_III;
- }
- }
- }
-}
-
-static int me8255_io_reset_subdevice(struct me_subdevice *subdevice,
- struct file *filep, int flags)
-{
- me8255_subdevice_t *instance;
-
- PDEBUG("executed.\n");
-
- instance = (me8255_subdevice_t *) subdevice;
-
- if (flags) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- spin_lock(instance->ctrl_reg_lock);
- *instance->ctrl_reg_mirror &=
- ~(ME8255_PORT_0_OUTPUT << instance->dio_idx);
- outb(get_mode_from_mirror(*instance->ctrl_reg_mirror),
- instance->ctrl_reg);
- spin_unlock(instance->ctrl_reg_lock);
-
- outb(0, instance->port_reg);
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8255_io_single_config(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int single_config,
- int ref,
- int trig_chan,
- int trig_type, int trig_edge, int flags)
-{
- me8255_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me8255_subdevice_t *) subdevice;
-
- if (flags & ~ME_IO_SINGLE_CONFIG_DIO_BYTE) {
- PERROR("Invalid flag specified.\n");
- return ME_ERRNO_INVALID_FLAGS;
- }
-
- if (channel) {
- PERROR("Invalid channel.\n");
- return ME_ERRNO_INVALID_CHANNEL;
- }
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
- spin_lock(instance->ctrl_reg_lock);
- *instance->ctrl_reg_mirror &=
- ~(ME8255_PORT_0_OUTPUT << instance->dio_idx);
- outb(get_mode_from_mirror(*instance->ctrl_reg_mirror),
- instance->ctrl_reg);
- spin_unlock(instance->ctrl_reg_lock);
- } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
- spin_lock(instance->ctrl_reg_lock);
- *instance->ctrl_reg_mirror |=
- (ME8255_PORT_0_OUTPUT << instance->dio_idx);
- outb(get_mode_from_mirror(*instance->ctrl_reg_mirror),
- instance->ctrl_reg);
- spin_unlock(instance->ctrl_reg_lock);
- } else {
- PERROR("Invalid port direction.\n");
- err = ME_ERRNO_INVALID_SINGLE_CONFIG;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8255_io_single_read(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int *value, int time_out, int flags)
-{
- me8255_subdevice_t *instance;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me8255_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- *value = inb(instance->port_reg) & (0x1 << channel);
- } else {
- PERROR("Invalid bit number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- *value = inb(instance->port_reg);
- } else {
- PERROR("Invalid byte number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8255_io_single_write(struct me_subdevice *subdevice,
- struct file *filep,
- int channel,
- int value, int time_out, int flags)
-{
- me8255_subdevice_t *instance;
- uint8_t byte;
- int err = ME_ERRNO_SUCCESS;
-
- PDEBUG("executed.\n");
-
- instance = (me8255_subdevice_t *) subdevice;
-
- ME_SUBDEVICE_ENTER;
-
- spin_lock(&instance->subdevice_lock);
- switch (flags) {
- case ME_IO_SINGLE_TYPE_DIO_BIT:
- if ((channel >= 0) && (channel < 8)) {
- if (*instance->
- ctrl_reg_mirror & (ME8255_PORT_0_OUTPUT <<
- instance->dio_idx)) {
- byte = inb(instance->port_reg);
-
- if (value)
- byte |= 0x1 << channel;
- else
- byte &= ~(0x1 << channel);
-
- outb(byte, instance->port_reg);
- } else {
- PERROR("Port not in output mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid bit number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- case ME_IO_SINGLE_NO_FLAGS:
- case ME_IO_SINGLE_TYPE_DIO_BYTE:
- if (channel == 0) {
- if (*instance->
- ctrl_reg_mirror & (ME8255_PORT_0_OUTPUT <<
- instance->dio_idx)) {
- outb(value, instance->port_reg);
- } else {
- PERROR("Port not in output mode.\n");
- err = ME_ERRNO_PREVIOUS_CONFIG;
- }
- } else {
- PERROR("Invalid byte number.\n");
- err = ME_ERRNO_INVALID_CHANNEL;
- }
- break;
-
- default:
- PERROR("Invalid flags specified.\n");
- err = ME_ERRNO_INVALID_FLAGS;
- }
- spin_unlock(&instance->subdevice_lock);
-
- ME_SUBDEVICE_EXIT;
-
- return err;
-}
-
-static int me8255_query_number_channels(struct me_subdevice *subdevice,
- int *number)
-{
- PDEBUG("executed.\n");
- *number = ME8255_NUMBER_CHANNELS;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8255_query_subdevice_type(struct me_subdevice *subdevice,
- int *type, int *subtype)
-{
- PDEBUG("executed.\n");
- *type = ME_TYPE_DIO;
- *subtype = ME_SUBTYPE_SINGLE;
- return ME_ERRNO_SUCCESS;
-}
-
-static int me8255_query_subdevice_caps(struct me_subdevice *subdevice,
- int *caps)
-{
- PDEBUG("executed.\n");
- *caps = ME_CAPS_DIO_DIR_BYTE;
- return ME_ERRNO_SUCCESS;
-}
-
-me8255_subdevice_t *me8255_constructor(uint32_t device_id,
- uint32_t reg_base,
- unsigned int me8255_idx,
- unsigned int dio_idx,
- int *ctrl_reg_mirror,
- spinlock_t *ctrl_reg_lock)
-{
- me8255_subdevice_t *subdevice;
- int err;
-
- PDEBUG("executed.\n");
-
- /* Allocate memory for subdevice instance */
- subdevice = kmalloc(sizeof(me8255_subdevice_t), GFP_KERNEL);
-
- if (!subdevice) {
- PERROR("Cannot get memory for 8255 instance.\n");
- return NULL;
- }
-
- memset(subdevice, 0, sizeof(me8255_subdevice_t));
-
- /* Check if counter index is out of range */
-
- if (dio_idx > 2) {
- PERROR("DIO index is out of range.\n");
- kfree(subdevice);
- return NULL;
- }
-
- /* Initialize subdevice base class */
- err = me_subdevice_init(&subdevice->base);
-
- if (err) {
- PERROR("Cannot initialize subdevice base class instance.\n");
- kfree(subdevice);
- return NULL;
- }
- // Initialize spin locks.
- spin_lock_init(&subdevice->subdevice_lock);
-
- subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
- /* Save the pointer to global port settings */
- subdevice->ctrl_reg_mirror = ctrl_reg_mirror;
-
- /* Save type of Meilhaus device */
- subdevice->device_id = device_id;
-
- /* Save the indices */
- subdevice->me8255_idx = me8255_idx;
- subdevice->dio_idx = dio_idx;
-
- /* Do device specific initialization */
- switch (device_id) {
- case PCI_DEVICE_ID_MEILHAUS_ME1400:
- case PCI_DEVICE_ID_MEILHAUS_ME14E0:
-
- case PCI_DEVICE_ID_MEILHAUS_ME140A:
- case PCI_DEVICE_ID_MEILHAUS_ME14EA:
- /* Check if 8255 index is out of range */
- if (me8255_idx > 0) {
- PERROR("8255 index is out of range.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
-
- case PCI_DEVICE_ID_MEILHAUS_ME140B: /* Fall through */
- case PCI_DEVICE_ID_MEILHAUS_ME14EB:
- /* Check if 8255 index is out of range */
- if (me8255_idx > 1) {
- PERROR("8255 index is out of range.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
-
- /* Get the registers */
- if (me8255_idx == 0) {
- subdevice->ctrl_reg = reg_base + ME1400AB_PORT_A_CTRL;
- subdevice->port_reg =
- reg_base + ME1400AB_PORT_A_0 + dio_idx;
- } else if (me8255_idx == 1) {
- subdevice->ctrl_reg = reg_base + ME1400AB_PORT_B_CTRL;
- subdevice->port_reg =
- reg_base + ME1400AB_PORT_B_0 + dio_idx;
- }
-
- break;
-
- case PCI_DEVICE_ID_MEILHAUS_ME140C:
- /* Check if 8255 index is out of range */
- if (me8255_idx > 0) {
- PERROR("8255 index is out of range.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
-
- case PCI_DEVICE_ID_MEILHAUS_ME140D: /* Fall through */
- /* Check if 8255 index is out of range */
- if (me8255_idx > 1) {
- PERROR("8255 index is out of range.\n");
- me_subdevice_deinit(&subdevice->base);
- kfree(subdevice);
- return NULL;
- }
-
- /* Get the registers */
- if (me8255_idx == 0) {
- subdevice->ctrl_reg = reg_base + ME1400CD_PORT_A_CTRL;
- subdevice->port_reg =
- reg_base + ME1400CD_PORT_A_0 + dio_idx;
- } else if (me8255_idx == 1) {
- subdevice->ctrl_reg = reg_base + ME1400CD_PORT_B_CTRL;
- subdevice->port_reg =
- reg_base + ME1400CD_PORT_B_0 + dio_idx;
- }
-
- break;
-
- default:
- PERROR("Unknown device type. dev ID: 0x%04x\n", device_id);
-
- me_subdevice_deinit(&subdevice->base);
-
- kfree(subdevice);
-
- return NULL;
- }
-
- /* Overload subdevice base class methods. */
- subdevice->base.me_subdevice_io_reset_subdevice =
- me8255_io_reset_subdevice;
- subdevice->base.me_subdevice_io_single_config = me8255_io_single_config;
- subdevice->base.me_subdevice_io_single_read = me8255_io_single_read;
- subdevice->base.me_subdevice_io_single_write = me8255_io_single_write;
- subdevice->base.me_subdevice_query_number_channels =
- me8255_query_number_channels;
- subdevice->base.me_subdevice_query_subdevice_type =
- me8255_query_subdevice_type;
- subdevice->base.me_subdevice_query_subdevice_caps =
- me8255_query_subdevice_caps;
-
- return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8255.h b/drivers/staging/meilhaus/me8255.h
deleted file mode 100644
index 3382300..0000000
--- a/drivers/staging/meilhaus/me8255.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file me8255.h
- *
- * @brief Meilhaus PIO 8255 implementation.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME8255_H_
-#define _ME8255_H_
-
-#include "mesubdevice.h"
-#include "meslock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The 8255 subdevice class.
- */
-typedef struct me8255_subdevice {
- /* Inheritance */
- me_subdevice_t base; /**< The subdevice base class. */
-
- /* Attributes */
- spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
-
- int *ctrl_reg_mirror; /**< Pointer to mirror of the control register. */
- spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg and #ctrl_reg_mirror from concurrent access. */
-
- uint32_t device_id; /**< The PCI device id of the device holding the 8255 chip. */
- int me8255_idx; /**< The index of the 8255 chip on the device. */
- int dio_idx; /**< The index of the DIO port on the 8255 chip. */
-
- unsigned long port_reg; /**< Register to read or write a value from or to the port respectively. */
- unsigned long ctrl_reg; /**< Register to configure the 8255 modes. */
-} me8255_subdevice_t;
-
-/**
- * @brief The constructor to generate a 8255 instance.
- *
- * @param device_id The kind of Meilhaus device holding the 8255.
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param me8255_idx The index of the 8255 chip on the Meilhaus device.
- * @param dio_idx The index of the counter inside a 8255 chip.
- * @param ctr_reg_mirror Pointer to mirror of control register.
- * @param ctrl_reg_lock Pointer to spin lock protecting the 8255 control register and #ctrl_reg_mirror from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8255_subdevice_t *me8255_constructor(uint32_t device_id,
- uint32_t reg_base,
- unsigned int me8255_idx,
- unsigned int dio_idx,
- int *ctrl_reg_mirror,
- spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8255_reg.h b/drivers/staging/meilhaus/me8255_reg.h
deleted file mode 100644
index d1dea1a..0000000
--- a/drivers/staging/meilhaus/me8255_reg.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file me8255_reg.h
- *
- * @brief 8255 counter register definitions.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME8255_REG_H_
-#define _ME8255_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8255_NUMBER_CHANNELS 8 /**< The number of channels per 8255 port. */
-
-#define ME1400AB_PORT_A_0 0x0000 /**< Port 0 offset. */
-#define ME1400AB_PORT_A_1 0x0001 /**< Port 1 offset. */
-#define ME1400AB_PORT_A_2 0x0002 /**< Port 2 offset. */
-#define ME1400AB_PORT_A_CTRL 0x0003 /**< Control register for 8255 A. */
-
-#define ME1400AB_PORT_B_0 0x0008 /**< Port 0 offset. */
-#define ME1400AB_PORT_B_1 0x0009 /**< Port 1 offset. */
-#define ME1400AB_PORT_B_2 0x000A /**< Port 2 offset. */
-#define ME1400AB_PORT_B_CTRL 0x000B /**< Control register for 8255 B. */
-
-#define ME1400CD_PORT_A_0 0x0000 /**< Port 0 offset. */
-#define ME1400CD_PORT_A_1 0x0001 /**< Port 1 offset. */
-#define ME1400CD_PORT_A_2 0x0002 /**< Port 2 offset. */
-#define ME1400CD_PORT_A_CTRL 0x0003 /**< Control register for 8255 A. */
-
-#define ME1400CD_PORT_B_0 0x0040 /**< Port 0 offset. */
-#define ME1400CD_PORT_B_1 0x0041 /**< Port 1 offset. */
-#define ME1400CD_PORT_B_2 0x0042 /**< Port 2 offset. */
-#define ME1400CD_PORT_B_CTRL 0x0043 /**< Control register for 8255 B. */
-
-#define ME8255_MODE_OOO 0x80 /**< Port 2 = Output, Port 1 = Output, Port 0 = Output */
-#define ME8255_MODE_IOO 0x89 /**< Port 2 = Input, Port 1 = Output, Port 0 = Output */
-#define ME8255_MODE_OIO 0x82 /**< Port 2 = Output, Port 1 = Input, Port 0 = Output */
-#define ME8255_MODE_IIO 0x8B /**< Port 2 = Input, Port 1 = Input, Port 0 = Output */
-#define ME8255_MODE_OOI 0x90 /**< Port 2 = Output, Port 1 = Output, Port 0 = Input */
-#define ME8255_MODE_IOI 0x99 /**< Port 2 = Input, Port 1 = Output, Port 0 = Input */
-#define ME8255_MODE_OII 0x92 /**< Port 2 = Output, Port 1 = Input, Port 0 = Input */
-#define ME8255_MODE_III 0x9B /**< Port 2 = Input, Port 1 = Input, Port 0 = Input */
-
-#define ME8255_PORT_0_OUTPUT 0x1 /**< If set in mirror then port 0 is in output mode. */
-#define ME8255_PORT_1_OUTPUT 0x2 /**< If set in mirror then port 1 is in output mode. */
-#define ME8255_PORT_2_OUTPUT 0x4 /**< If set in mirror then port 2 is in output mode. */
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/mecirc_buf.h b/drivers/staging/meilhaus/mecirc_buf.h
deleted file mode 100644
index 5166585..0000000
--- a/drivers/staging/meilhaus/mecirc_buf.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * @file mecirc_buf.h
- *
- * @brief Meilhaus circular buffer implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _MECIRC_BUF_H_
-#define _MECIRC_BUF_H_
-
-# ifdef __KERNEL__
-
-# ifdef BOSCH
-
-typedef struct me_circ_buf {
- unsigned int mask;
-// unsigned int count;
- uint32_t *buf;
- int volatile head;
- int volatile tail;
-} me_circ_buf_t;
-
-static inline int me_circ_buf_values(me_circ_buf_t * buf)
-{
-// return ((buf->head - buf->tail) & (buf->count - 1));
- return ((buf->head - buf->tail) & (buf->mask));
-}
-
-static inline int me_circ_buf_space(me_circ_buf_t * buf)
-{
-// return ((buf->tail - (buf->head + 1)) & (buf->count - 1));
- return ((buf->tail - (buf->head + 1)) & (buf->mask));
-}
-
-static inline int me_circ_buf_values_to_end(me_circ_buf_t * buf)
-{
- int end;
- int n;
-// end = buf->count - buf->tail;
-// n = (buf->head + end) & (buf->count - 1);
- end = buf->mask + 1 - buf->tail;
- n = (buf->head + end) & (buf->mask);
- return (n < end) ? n : end;
-}
-
-static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf)
-{
- int end;
- int n;
-
-// end = buf->count - 1 - buf->head;
-// n = (end + buf->tail) & (buf->count - 1);
- end = buf->mask - buf->head;
- n = (end + buf->tail) & (buf->mask);
- return (n <= end) ? n : (end + 1);
-}
-
-#define _CBUFF_32b_t
-
-# else //~BOSCH
-/// @note buf->mask = buf->count-1 = ME4600_AI_CIRC_BUF_COUNT-1
-
-# ifdef _CBUFF_32b_t
- //32 bit
-typedef struct me_circ_buf_32b {
- int volatile head;
- int volatile tail;
- unsigned int mask; //buffor size-1 must be 2^n-1 to work
- uint32_t *buf;
-} me_circ_buf_t;
-# else
- //16 bit
-typedef struct me_circ_buf_16b {
- int volatile head;
- int volatile tail;
- unsigned int mask; //buffor size-1 must be 2^n-1 to work
- uint16_t *buf;
-} me_circ_buf_t;
-# endif //_CBUFF_32b_t
-
-/** How many values is in buffer */
-static inline int me_circ_buf_values(me_circ_buf_t * buf)
-{
- return ((buf->head - buf->tail) & (buf->mask));
-}
-
-/** How many space left */
-static inline int me_circ_buf_space(me_circ_buf_t * buf)
-{
- return ((buf->tail - (buf->head + 1)) & (buf->mask));
-}
-
-/** How many values can be read from buffor in one chunck. */
-static inline int me_circ_buf_values_to_end(me_circ_buf_t * buf)
-{
- return (buf->tail <=
- buf->head) ? (buf->head - buf->tail) : (buf->mask - buf->tail +
- 1);
-}
-
-/** How many values can be write to buffer in one chunck. */
-static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf)
-{
- return (buf->tail <=
- buf->head) ? (buf->mask - buf->head + 1) : (buf->tail -
- buf->head - 1);
-}
-
-# endif //BOSCH
-# endif //__KERNEL__
-#endif //_MECIRC_BUF_H_
diff --git a/drivers/staging/meilhaus/mecommon.h b/drivers/staging/meilhaus/mecommon.h
deleted file mode 100644
index ef47c38..0000000
--- a/drivers/staging/meilhaus/mecommon.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * Source File :mecommon.h
- * Author :GG (Guenter Gebhardt) <g.gebhardt at meilhaus.de>
- * Author :KG (Krzysztof Gantzke) <k.gantzke at meilhaus.de>
- */
-
-#ifndef _MECOMMON_H_
-#define _MECOMMON_H_
-
-/*==================================================================
- The version of this release
- ================================================================*/
-
-#ifndef ME_VERSION_DRIVER
-/* Unknown version */
-# define ME_VERSION_DRIVER 0xFFFFFFFF
-#endif
-
-#ifndef LIBMEDRIVER_VERSION
-/* Unknown version */
-# define LIBMEDRIVER_VERSION 0xFFFFFFFF
-#endif
-
-#endif
diff --git a/drivers/staging/meilhaus/medebug.h b/drivers/staging/meilhaus/medebug.h
deleted file mode 100644
index dcfb97c..0000000
--- a/drivers/staging/meilhaus/medebug.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * @file medebug.h
- *
- * @brief Debugging defines.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support at meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke (k.gantzke at meilhaus.de)
- */
-
-#ifndef _MEDEBUG_H_
-#define _MEDEBUG_H_
-
-#ifdef __KERNEL__
-
-#include <linux/kernel.h>
-
-//Messages control.
-
-#ifdef MEDEBUG_TEST_ALL /* Switch to enable all info messages. */
-# ifndef MEDEBUG_TEST
-# define MEDEBUG_TEST
-# endif
-# ifndef MEDEBUG_TEST_INFO
-# define MEDEBUG_TEST_INFO
-# endif
-# ifndef MEDEBUG_DEBUG_REG
-# define MEDEBUG_DEBUG_REG /* Switch to enable registry access debuging messages. */
-# endif
-# ifndef MEDEBUG_DEBUG_LOCKS
-# define MEDEBUG_DEBUG_LOCKS /* Switch to enable locking messages. */
-# endif
-#endif
-
-#ifdef MEDEBUG_TEST_INFO /* Switch to enable info and test messages. */
-# ifndef MEDEBUG_INFO
-# define MEDEBUG_INFO /* Switch to enable info messages. */
-# endif
-# ifndef MEDEBUG_TEST
-# define MEDEBUG_TEST
-# endif
-#endif
-
-#ifdef MEDEBUG_TEST /* Switch to enable debug test messages. */
-# ifndef MEDEBUG_DEBUG
-# define MEDEBUG_DEBUG /* Switch to enable debug messages. */
-# endif
-# ifndef MEDEBUG_ERROR
-# define MEDEBUG_ERROR /* Switch to enable error messages. */
-# endif
-#endif
-
-#ifdef MEDEBUG_ERROR /* Switch to enable error messages. */
-# ifndef MEDEBUG_ERROR_CRITICAL /* Also critical error messages. */
-# define MEDEBUG_ERROR_CRITICAL /* Switch to enable high importance error messages. */
-# endif
-#endif
-
-#undef PDEBUG /* Only to be sure. */
-#undef PINFO /* Only to be sure. */
-#undef PERROR /* Only to be sure. */
-#undef PERROR_CRITICAL /* Only to be sure. */
-#undef PDEBUG_REG /* Only to be sure. */
-#undef PDEBUG_LOCKS /* Only to be sure. */
-#undef PSECURITY /* Only to be sure. */
-#undef PLOG /* Only to be sure. */
-
-#ifdef MEDEBUG_DEBUG
-# define PDEBUG(fmt, args...) \
- printk(KERN_DEBUG"ME_DRV D: <%s> " fmt, __func__, ##args)
-#else
-# define PDEBUG(fmt, args...)
-#endif
-
-#ifdef MEDEBUG_DEBUG_LOCKS
-# define PDEBUG_LOCKS(fmt, args...) \
- printk(KERN_DEBUG"ME_DRV L: <%s> " fmt, __func__, ##args)
-#else
-# define PDEBUG_LOCKS(fmt, args...)
-#endif
-
-#ifdef MEDEBUG_DEBUG_REG
-# define PDEBUG_REG(fmt, args...) \
- printk(KERN_DEBUG"ME_DRV R: <%s:%d> REG:" fmt, __func__, __LINE__, ##args)
-#else
-# define PDEBUG_REG(fmt, args...)
-#endif
-
-#ifdef MEDEBUG_INFO
-# define PINFO(fmt, args...) \
- printk(KERN_INFO"ME_DRV I: " fmt, ##args)
-#else
-# define PINFO(fmt, args...)
-#endif
-
-#ifdef MEDEBUG_ERROR
-# define PERROR(fmt, args...) \
- printk(KERN_ERR"ME_DRV E: <%s:%i> " fmt, __FILE__, __LINE__, ##args)
-#else
-# define PERROR(fmt, args...)
-#endif
-
-#ifdef MEDEBUG_ERROR_CRITICAL
-# define PERROR_CRITICAL(fmt, args...) \
- printk(KERN_CRIT"ME_DRV C: <%s:%i> " fmt, __FILE__, __LINE__, ##args)
-#else
-# define PERROR_CRITICAL(fmt, args...)
-#endif
-
-//This debug is only to detect logical errors!
-# define PSECURITY(fmt, args...) \
- printk(KERN_CRIT"ME_DRV SECURITY: <%s:%s:%i> " fmt, __FILE__, __func__, __LINE__, ##args)
-//This debug is to keep track in customers' system
-# define PLOG(fmt, args...) \
- printk(KERN_INFO"ME_DRV: " fmt, ##args)
-
-//This debug is to check new parts during development
-#ifdef MEDEBUG_DEVELOP
-# define PDEVELOP(fmt, args...) \
- printk(KERN_CRIT"ME_DRV: <%s:%s:%i> " fmt, __FILE__, __func__, __LINE__, ##args)
-#else
-# define PDEVELOP(fmt, args...)
-#endif
-
-#endif //__KERNEL__
-#endif //_MEDEBUG_H_
diff --git a/drivers/staging/meilhaus/medefines.h b/drivers/staging/meilhaus/medefines.h
deleted file mode 100644
index 6158ef5..0000000
--- a/drivers/staging/meilhaus/medefines.h
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support at meilhaus.de)
- *
- * Source File : medefines.h
- * Author : GG (Guenter Gebhardt) <g.gebhardt at meilhaus.de>
- * Author : KG (Krzysztof Gantzke) <k.gantzke at meilhaus.de>
- */
-
-#ifndef _MEDEFINES_H_
-#define _MEDEFINES_H_
-
-/*==================================================================
- General
- ================================================================*/
-
-#define ME_VALUE_NOT_USED 0x0
-#define ME_VALUE_INVALID ~0x0
-
-/*==================================================================
- Defines common to access functions
- ================================================================*/
-
-#define ME_LOCK_RELEASE 0x00010001
-#define ME_LOCK_SET 0x00010002
-#define ME_LOCK_CHECK 0x00010003
-
-/*==================================================================
- Defines meOpen function
- ================================================================*/
-
-#define ME_OPEN_NO_FLAGS 0x0
-
-/*==================================================================
- Defines meClose function
- ================================================================*/
-
-#define ME_CLOSE_NO_FLAGS 0x0
-
-/*==================================================================
- Defines meLockDriver function
- ================================================================*/
-
-#define ME_LOCK_DRIVER_NO_FLAGS 0x0
-
-/*==================================================================
- Defines meLockDevice function
- ================================================================*/
-
-#define ME_LOCK_DEVICE_NO_FLAGS 0x0
-
-/*==================================================================
- Defines meLockSubdevice function
- ================================================================*/
-
-#define ME_LOCK_SUBDEVICE_NO_FLAGS 0x0
-
-
-/*==================================================================
- Defines common to error functions
- ================================================================*/
-
-#define ME_ERROR_MSG_MAX_COUNT 256
-
-#define ME_SWITCH_DISABLE 0x00020001
-#define ME_SWITCH_ENABLE 0x00020002
-
-/*==================================================================
- Defines common to io functions
- ================================================================*/
-
-#define ME_REF_DIO_FIFO_LOW 0x00030001
-#define ME_REF_DIO_FIFO_HIGH 0x00030002
-
-#define ME_REF_CTR_PREVIOUS 0x00040001
-#define ME_REF_CTR_INTERNAL_1MHZ 0x00040002
-#define ME_REF_CTR_INTERNAL_10MHZ 0x00040003
-#define ME_REF_CTR_EXTERNAL 0x00040004
-
-#define ME_REF_AI_GROUND 0x00050001
-#define ME_REF_AI_DIFFERENTIAL 0x00050002
-
-#define ME_REF_AO_GROUND 0x00060001
-
-#define ME_TRIG_CHAN_DEFAULT 0x00070001
-#define ME_TRIG_CHAN_SYNCHRONOUS 0x00070002
-
-#define ME_TRIG_TYPE_NONE 0x00000000
-#define M